所以我有一个我无法弄清楚的问题。我正在用C编写一些代码。我一直在处理从网络中读取似乎随机工作的问题。
我最终将其追溯到代码中的字符串数量。我不敢相信,但我已经深入验证了它。
代码库相当庞大,所以我不确定字符串奇偶校验的总数。但是我知道,如果我添加一个奇数,那么程序可以工作,如果我添加一个偶数,它就不会。
只是为了澄清当我说它不起作用时,它仍然构建并执行,但每当我尝试通过网络读取任何内容时,我得到的只是0。当它工作时,我得到了正确的数据。
有没有人听说过这样的事情?或者知道可能导致这种情况的原因是什么?我可以看到程序的数据部分是否变得太大并且开始阻碍其他代码的空间,但事实上它的奇怪/偶数事情让我感到困惑。
谢谢
编辑(添加更多信息):
该平台是一个定制设计的设备。代码库是redboot,但它已经为自定义设备进行了大幅改动。
以剪切为例:
//这将起作用,因为它是奇数个字符串。
char* str1 = "test";
char* str2 = "test2";
char* str3 = "test3";
int i = strlen(str1) + strlen(str2) + strlen(str3);
......................................
如果我要将最后一行更改为
int i = strlen(str1) + str(len2);
这样str3就会被编译器优化掉,然后代码将不再起作用。我用各种长度的字符串测试了这么多次都导致了相同的奇/偶行为。 (我刚刚被发送到调试日志,因此没有进行优化。没有任何花哨的事情。)
Edit2:上面的代码可以放在代码库中的任何地方,它会导致同样的问题。它是否被执行无关紧要,这让我相信它不是堆栈溢出。
答案 0 :(得分:6)
随机刺入黑暗的时间......
从网络套接字读取时常见的误解是10个字节的read()
将返回接下来的10个字节。它不会。它将返回最多10个字节,您可能需要多次调用read()
以获取所需的所有数据。
答案 1 :(得分:4)
我以前没有听说过这样的问题。你听起来很沮丧,你说你的代码库相当庞大。如果解决问题很重要,我建议您尝试使用较少量的代码重现该问题。如果您发布一些代码示例来说明问题,它也可以帮助您在此获得答案。
答案 2 :(得分:4)
你从哪里获取断言,它与字符串数量的奇偶校验有关?如果我试着仔细解释你所说的内容,这告诉我代码中的微小变化会让你触发意想不到的行为。
闻起来像堆栈溢出。您是否在堆栈上分配大型数组或字符串,然后对它们read
和write
进行分配?
在这种情况下,尝试通过malloc/free
动态分配/释放这些大缓冲区。
答案 3 :(得分:2)
这是猜测。
假设平台是32位。
也许编译器在8字节边界内将程序的某些数据结构与内存对齐。您的数据段中有大量的字符串指针,也可能是其他一些东西。如果存在奇数个字符串,则需要8字节对齐的下一个字节在其前面有四个字节的填充。如果有一个偶数个字符串,则没有填充。
在8字节对齐的对象之前的任何数据片段都有溢出错误,它只会破坏它之后的1到4个字节之间的内容。如果在这件事之后有填充,没有什么不好的事情发生。如果没有填充,则八字节对齐的对象会被删除。
答案 4 :(得分:1)
如果你有类似
的东西char buf[10];
long var;
strcpy(buf, "ganz viel text");
您可能会或可能不会使用变量“var”获得分段违规或奇怪的行为。如果你在代码中加入更多调试文本,链接器可能会重新分配变量,或者编译器可能会进行其他代码优化,并在内存中重新分配空间分配。