malloc内存损坏,fopen

时间:2011-10-19 15:47:37

标签: c sockets udp malloc fopen

我尝试过使用GDB和Valgrind,但我似乎无法确定问题所在。 有趣的是,程序在正常执行和GDB期间崩溃,但不是Valgrid。

为了帮助您遵循代码,继承了该计划的基本要点: 通过套接字和UDP与服务器通信以传输文件,并处理一些基本的数据包丢失。

我不会共享服务器的代码,因为我知道问题不存在。 可能会让一些人感到困惑的一点是,我正在使用数字生成器自己实现数据包丢失。现在它没有做任何事情,除了让程序使用另一个recvfrom。

为了引导您完成程序输出,客户端告诉服务器它想要什么文件,服务器告诉客户端文件要发送多大,然后以块(每次10个字符)发送它。

输出显示发送了什么块,接收了多少字符以及串联字符串是什么。

文件传输取决于我所知道的,它只是我用来编写接收文件的fopen调用给我带来麻烦。不确定是否与我的malloc电话有关。

以下是源代码:

pastebin.com/Z79hvw6L

以下是CLI执行的输出,以及Valgrind(GDB似乎不再提供任何信息):

请注意,CLI提供了malloc内存损坏错误,而Valgrind则没有。

CLI:http://pastebin.com/qdTKMCD2

VALGRIND:http://pastebin.com/8inRygnU

感谢您的帮助!

添加了GDB Backtrace结果

======= Backtrace: =========
/lib/i386-linux-gnu/libc.so.6(+0x6b961)[0x19a961]
/lib/i386-linux-gnu/libc.so.6(+0x6e15d)[0x19d15d]
/lib/i386-linux-gnu/libc.so.6(__libc_malloc+0x63)[0x19ef53]
/lib/i386-linux-gnu/libc.so.6(+0x5c2b8)[0x18b2b8]
/lib/i386-linux-gnu/libc.so.6(fopen+0x2c)[0x18b38c]
/home/---/client[0x8048dc2]
/lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xe7)[0x145e37]
/home/---/client[0x8048871]

也许这可以让某人了解错误所在的程序的哪个部分?

3 个答案:

答案 0 :(得分:3)

char chunk[10];
chunk[10] = '\0';

错了,chunk [10]是一个超过数组的。

一般来说,小心这样做

char filename[25];
scanf("%s",filename);

如果输入长文件名,则会丢失内存。使用fgets()会更好。您至少还想检查scanf是否成功,否则文件名中的以下strlen()无效。

第93行,buf[strlen(buf)-1]='\0';是危险的,如果缓冲区尚未终止,则不能使用strlen,如果buf为空字符串,则在使用strf [-1]进行索引时会丢弃内存。

编辑。 你的另一个问题是strcat(fullstring,chunk);,如果你碰巧收到的数据多于它可以容纳的数据,那么你的循环就无法控制停止附加到这个字符串。大小也可能是一个,因为你需要最后一个nul终结器的空间。至少要char * fullstring = malloc(sizeof(char)*filesize + 1 );但是你的循环真的需要检查它是不是写在那个缓冲区的末尾。

至于向buf添加一个nul终止符,recv调用返回你读取的字节数,所以如果你已经检查了recv是否有错误,请执行buf[numbytes] = 0,但这将关闭一个也是,因为你为buf分配了10个字节,你也尝试读取10个字节 - 但在C中,字符串也需要空间来容纳nul终结符。使buf 11字节大。或者recv()只有9个字节。

事实上,你离开了很多地方,所以开始计算你需要多少字节,然后把东西放进去。请记住,在C中,数组以索引0开头,而数组10只能由索引0到9索引。

答案 1 :(得分:2)

这(第93行)是可疑的:

buf[strlen(buf)-1]='\0';

更新此(第99,100行)也是错误的:

char chunk[10];
chunk[10] = '\0';

UPDATE2:缓冲区太小

char * fullstring = malloc(sizeof(char)*filesize); // line 103
...
strcat(fullstring,chunk); // line 124

UPDATE3: UDP是不可靠的。数据包的传输可能会失败(数据包可能会丢弃在发送方和接收方之间的任何位置),并且可能会以与发送数据包不同的顺序接收数据包。

答案 2 :(得分:1)

嗯,它应该不是现代操作系统的问题:但是你不检查malloc()返回的值是否为NULL。它崩溃的路线和信号是什么?