-4

我打算sprintf()从我的代码中删除,因为它不再需要在我的代码中。但是当我这样做时,它会导致分段错误,而它在那里工作正常。sprintf()请告诉我这个原因以及如何解决这个问题问题。

unsigned char status_str[40]={0};
sprintf(status_str,"found HTTP:%dth time\n",(count+1));
4

2 回答 2

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 稍后)。

于 2013-05-03T12:10:04.383 回答
1

它到底在哪里发生了段错误?如果你真的只是删除它并且代码不再引用 status_str 那么它可能表明堆栈损坏。该错误可能发生在更早的某个地方并且它随机工作,但是当堆栈布局发生变化时,看似无关的代码部分可能会无缘无故地中断。

例如:如果较早的代码用一些值覆盖堆栈,并且这些值到达 status_str,则不会造成任何伤害,但是当它消失时,会覆盖其他内容,这可能会导致段错误。

这只是一个猜测。因此,您应该检查在调用该特定函数之前调用的代码。

澄清一下:它可以是任何内存,不一定是堆栈,这取决于它的定义位置。

于 2013-05-03T12:11:53.953 回答