Joe*_*ool 3 c debugging segmentation-fault printf-debugging
正如许多年轻程序员所做的那样,我学会了在代码中的不同点插入"here1","here2"等多个打印到控制台语句的有用性,以确定我的程序何时出错.在我的CS研究中,这种强力调试技术为我节省了很多次.但是,当我开始用C编程时,我偶然发现了一个有趣的问题.如果我试着跑
void* test;
printf("hello world");
test[5] = 234;
Run Code Online (Sandbox Code Playgroud)
当然,我为testChar而没有malloc'ing内存的段错误.但是,你会在逻辑上认为的"Hello World"将在赛格故障发生之前打印的,因为这是代码的流程,但以我的经验,它始终是赛格故障首先发生的情况,以及"世界你好"根本没有打印到控制台.(我没能测试这个确切的例子,但我遇到了这种使用在Linux中gcc的情况很多次了.)我猜这有两种编译器重新安排一些事情和/或printf的做使用某种异步刷新的缓冲区,因此不是立即的.这完全是我的猜测,因为我老实说不知道为什么会这样.在我使用的任何其他语言中,无论"testChar = ..."行引起什么问题,"hello world"仍会被打印,因此我可以确定问题所在.
我的问题是为什么在我编程C时会发生这种情况?为什么不首先打印你好世界?其次,有没有比这更好的C编程调试技术完成相同的基本操作?如何,一个简单/直观的方法来找到有问题的代码行?
编辑:我偶然给了一个工作的例子哈哈.我现在拥有的应该是一个段错误.有趣的是,通常当我不想要一个段落错误时,我得到一个,现在当我真正想要一个我编写法律代码时!
小智 9
您发布的代码完全合法,不应导致段错误 - 不需要malloc任何东西.您的问题必须在其他地方 - 请发布导致问题的最小代码示例.
编辑:您现在编辑的代码具有完全不同的含义.仍然,没有显示"hello world"的原因是输出缓冲区尚未刷新.试试addinig
fflush( stdout );
Run Code Online (Sandbox Code Playgroud)
在printf之后.
关于定位问题的根源,您有几个选择:
__FILE__和__LINE__C宏通过代码自由地散布printfsprintf写入缓冲的stdout.有时,在程序崩溃之前,缓冲区不会被刷新,因此您永远不会看到输出.避免这种情况的两种方法:
fprintf( stderr, "error string" );因为stderr没有缓冲.fflush( stdout );在printf调用之后添加一个调用.正如Neil和其他人所说,编写的代码很好.也就是说,直到你开始修改testChar指向的缓冲区.
“比如,有一种简单/直观的方法来查找有问题的代码行吗?”
使用 gdb(或任何其他调试器)。
要查找程序段错误的位置,请使用-g选项(包括调试符号)编译它,从gdb运行应用程序,它将因段错误而停止。
然后,您可以使用命令查看回溯bt,看看在哪一点出现了段错误。
例子:
> gdb ./x
(gdb) r
Starting program: /proj/cpp/arr/x
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_PROTECTION_FAILURE at address: 0x00000000
0x000019a9 in willfail () at main.cpp:22
22 *a = 3;
(gdb) bt
#0 0x000019a9 in willfail () at main.cpp:22
#1 0x00001e32 in main () at main.cpp:49
(gdb)
Run Code Online (Sandbox Code Playgroud)