我打算sprintf()
从我的代码中删除,因为它不再需要在我的代码中。但是当我这样做时,它会导致分段错误,而它在那里工作正常。sprintf()
请告诉我这个原因以及如何解决这个问题问题。
unsigned char status_str[40]={0};
sprintf(status_str,"found HTTP:%dth time\n",(count+1));
首先,不推荐使用sprintf(3)(或者至少不推荐,请参阅链接手册页的BUGS部分),这是一个危险的功能(因为可能存在缓冲区溢出)。您应该使用snprintf
(这是自 C99 以来的标准,即自上个世纪以来)和代码
snprintf (status_str, sizeof(status_str),
"found HTTP:%dth time\n", (count+1));
snprintf
首选的原因是sprintf
即使输出溢出缓冲区,snprintf
也不会溢出给定的大小,而sprintf
不知道任何大小限制,会溢出。
然后,如果您sprintf
避免了一些分段错误(假设它没有溢出status_str
),那么您已经受到程序中其他地方的一些未定义行为 的伤害。
我想sprintf
用一些恰好使它在以后工作的东西来填充可能[堆栈位置]一些未初始化的值。
我建议编译-Wall -Wextra -g
(改进代码直到你没有收到警告)并使用gdb
调试器(它的watch
命令很有帮助)。您还可以valgrind
用来寻找内存泄漏(以及一些未初始化的访问)。
如果您需要更多帮助,请显示更多源代码。
使用 GNU libc,您还可以使用asprintf来分配和填充一些malloc
堆区。这个函数是 GNU 特定的(你应该确保指针是free
-d 稍后)。
它到底在哪里发生了段错误?如果你真的只是删除它并且代码不再引用 status_str 那么它可能表明堆栈损坏。该错误可能发生在更早的某个地方并且它随机工作,但是当堆栈布局发生变化时,看似无关的代码部分可能会无缘无故地中断。
例如:如果较早的代码用一些值覆盖堆栈,并且这些值到达 status_str,则不会造成任何伤害,但是当它消失时,会覆盖其他内容,这可能会导致段错误。
这只是一个猜测。因此,您应该检查在调用该特定函数之前调用的代码。
澄清一下:它可以是任何内存,不一定是堆栈,这取决于它的定义位置。