=Start=
缘由:
学习需要
正文:
参考解答:
如下的一段代码,测试了好多次,完全想不通为什么?只能说坑太多,踩不完……(也可能是因为对C语言理解不深)
#include <stdio.h> #include <stdlib.h> #include <string.h> int main() { char *a = NULL; printf( "%s" , a); // OK '(null)' printf( "\n" ); // printf("%p", a); // OK '(nil)' // printf("\n"); // printf("%s", NULL); // OK '(null)' // printf("%d", NULL); // OK 0 // printf("%p", NULL); // OK '(nil)' // printf("\n"); // printf("\n%s\n", a); // OK '(null)' // printf("\n%s", a); // OK // printf("%s\0", a); // OK '(null)' // printf("%sabc", a); // OK '(null)abc' // printf("%s\t", a); // OK '(null) ' // printf("%p\n", a); // OK '(nil)' // printf("%s\n", *a); // core dump (warning: format specifies type 'char *' but the argument has type 'char') printf( "%s\n" , a); // core dump (@linux but OK @Mac) // printf("%s\n", NULL); // core dump (@linux but OK @Mac) // printf("test:%s\n", a); // OK return 0 ; } |
printf的某些地方用的不当的话就会出现:编译时没有Warning,不易察觉,运行时低概率不定期coredump,简直让人崩溃。
参考链接:
Printf ubuntu Segmentation fault (core dumped) #可能是系统或架构的问题,重装了之后就好了……
https://stackoverflow.com/questions/13894194/printf-ubuntu-segmentation-fault-core-dumped
Execution of printf() and Segmentation Fault
https://stackoverflow.com/questions/9469790/execution-of-printf-and-segmentation-fault
为什么打印log(比如printf)会经常碰到core dump?
http://blog.csdn.net/stpeace/article/details/51165723
printf大坑等着很多人——一次core dump经历及定位过程(printf打印C++ string的时候忘了.c_st()转化)
http://blog.csdn.net/stpeace/article/details/50334915
Core dump与backtrace
http://blog.cuicc.com/blog/2012/09/17/core-dump-and-backtrace/
C语言中如何用printf打印指针类型变量?
https://stackoverflow.com/questions/1055959/print-the-address-a-pointer-contains-in-c
https://stackoverflow.com/questions/9053658/correct-format-specifier-to-print-pointer-address
https://stackoverflow.com/questions/30354097/how-to-printf-a-memory-address-in-c
C语言结构体里的成员数组和指针
http://coolshell.cn/articles/11377.html
=END=
《 “由printf导致的「Segmentation fault (core dumped)」” 》 有 5 条评论
为什么打印log(比如printf)会经常碰到core dump?
http://blog.csdn.net/stpeace/article/details/51165723
`
通过printf和vsprintf的源码来看,如果传给它的参数个数、类型不匹配,就会导致内存赋值错误,然后core dump也就来啦。
`
一道 C 语言 printf 的经典题目
https://www.v2ex.com/t/372396
http://www.revotu.com/advanced-c-interview-questions-and-answers.html
printf 函数的详细实现流程
http://www.maizure.org/projects/printf/index.html
你可能不知道的printf
https://mp.weixin.qq.com/s?__biz=MzI2OTA3NTk3Ng==&mid=2649284608&idx=2&sn=3449445af2ff6db0525c78cd08a48b4e
每天都在用printf,你知道变长参数是怎么实现的吗
https://mp.weixin.qq.com/s/Pbu_Vvn1IuAIrt3VP6jCCQ
`
一些总结
# 变长参数实现的基本原理
对于x86来说,函数参数入栈顺序为从右往左,因此,在知道第一个参数地址之后,我们能够通过地址偏移获取其他参数,虽然x86-64在实现上略有不同,但`对于开发者使用来说,实现变长参数函数没有32位和64位的区别。
# 变长参数实现注意事项
1.…前的参数可以有1个或多个,但前一个必须是确定类型。
2.传入参数会可能会出现类型提升。
3.va_arg的type类型不能是char,short int,float等类型,否则取值不正确,原因为第2点。
4.va_arg不能往回取参数,但可以使用va_copy拷贝va_list,以备后用。
5.变长参数类型注意做好检查,例如可以采用printf的占位符方式等等。
6.即便printf有类型检查,但也要注意参数匹配,例如,将int类型匹配%s打印,将会出现严重问题。
7.当传入参数个数少于使用的个数时,可能会出现严重问题,当传入参数大于使用的个数时,多出的参数不会被处理使用。
8.注意字节对齐问题。
`