我打算从我的代码中移除sprintf()
,因为我的代码中不再需要它。但是当我这样做时,它会导致分段错误,而当sprintf()
存在时它会正常工作请告诉我原因,以及如何解决这个问题。
unsigned char status_str[40]={0};
sprintf(status_str,"found HTTP:%dth time\n",(count+1));
答案 0 :(得分: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
),那么您已经被其他地方的某些undefined behavior 所伤害你的程序中有em> 。
我会想象,sprintf
可能会填充一些未初始化的值的堆栈位置,而某些东西恰好会让它在以后运行。
我建议使用-Wall -Wextra -g
进行编译(在没有警告的情况下改进代码)并使用gdb
调试器(其watch
命令很有帮助)。您还可以使用valgrind
来搜寻内存泄漏(以及某些未初始化的访问权限)。
如果您需要更多帮助,请显示更多源代码。
使用GNU libc,您还可以使用asprintf来分配和填充一些堆 - malloc
- 区域。这个函数是特定于GNU的(你应该确保指针是free
- d稍后)。
答案 1 :(得分:1)
它到底在哪里?如果你真的只是删除它并且代码不再引用status_str那么它可能表明堆栈损坏。错误可能在某个地方发生,并且随机工作,但是当堆栈布局发生变化时,代码中看似无关的部分可能会因为没有明显原因而中断。
例如:如果较早的代码用一些值覆盖堆栈,并且这些值到达status_str,则不会造成任何损害,但是当它消失时,会覆盖其他内容,这可能会导致段错误。
但这只是一个猜测。因此,您应该检查在调用特定函数之前调用的代码。
澄清:它可以是任何内存,而不是堆栈的必要内容,取决于它的定义位置。