简体   繁体   English

malloc内存损坏,fopen

[英]malloc memory corruption, fopen

I've tried using GDB and Valgrind, but I can't seem to pinpoint the problem. 我尝试过使用GDB和Valgrind,但我似乎无法确定问题所在。 Interestingly, the program crashes during normal execution and GDB, but not Valgrid. 有趣的是,程序在正常执行和GDB期间崩溃,但不是Valgrid。

To help you follow along with the code, heres the basic point of the program: Communicate with a server via sockets and UDP to transfer a file, and handle some basic packet loss. 为了帮助您遵循代码,继承了程序的基本要点:通过套接字和UDP与服务器通信以传输文件,并处理一些基本的数据包丢失。

I won't share the server's code, because I know the issue isn't there. 我不会共享服务器的代码,因为我知道问题不存在。 The point that might confuse some, is that I'm implementing packet loss myself, with a number generator. 可能会让一些人感到困惑的一点是,我正在使用数字生成器自己实现数据包丢失。 Right now it doesn't do anything really, besides make the program use another recvfrom. 现在它没有做任何事情,除了让程序使用另一个recvfrom。

To guide you throught the programs output, the client tells the server what file it wants, the server tells the client how big the file is it's going to send, and then sends it in chunks (of 10 characters at a time). 为了引导您完成程序输出,客户端告诉服务器它想要什么文件,服务器告诉客户端文件将要发送多大,然后以块(每次10个字符)发送它。

The output shows what chunk is sent, how many characters were received, and what the concatenated string is. 输出显示发送了什么块,接收了多少字符以及串联字符串是什么。

The file transfer succeeds from what i can tell, its just the fopen call that I use to write the received file that is giving me trouble. 文件传输取决于我所知道的,它只是我用来编写接收文件的fopen调用给我带来麻烦。 Not sure if it's to do with my malloc call or not. 不确定是否与我的malloc电话有关。

Here is the source code: 这是源代码:

pastebin.com/Z79hvw6L pastebin.com/Z79hvw6L

Here are the outputs from CLI execution, and Valgrind (GDB doesn't seem to give any more info): 以下是CLI执行的输出,以及Valgrind(GDB似乎不再提供任何信息):

Notice the CLI gives a malloc memory corruption error, and Valgrind doesn't. 请注意,CLI给出了malloc内存损坏错误,而Valgrind则没有。

CLI: http://pastebin.com/qdTKMCD2 CLI: http//pastebin.com/qdTKMCD2

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

Thanks for any help! 谢谢你的帮助!

Added the GDB Backtrace results 添加了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]

Maybe this could give someone an insight as to what part of the program the error is in? 也许这可以让某人了解错误所在的程序的哪个部分?

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

is wrong, chunk[10] is one past the array. 错了,chunk [10]是一个超过数组的人。

And in general, be careful with doing this 一般来说,要小心这样做

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

If you enter a long filename, you'll trash memory. 如果输入长文件名,则会丢失内存。 using fgets() would be better. 使用fgets()会更好。 You also would at least want to check if scanf succeeds, else the following strlen() on filename isn't valid. 您还至少要检查scanf是否成功,否则文件名上的以下strlen()无效。

line 93, buf[strlen(buf)-1]='\\0'; 第93行, buf[strlen(buf)-1]='\\0'; is dangerous, you can't use strlen if the buffer isn't already nul terminated, and you trash memory if buf is an empty string, as you index buf[-1]. 是危险的,如果缓冲区尚未终止,则不能使用strlen,如果buf为空字符串,则在使用strf [-1]进行索引时会丢弃内存。

Edit. 编辑。 Your other problem is strcat(fullstring,chunk); 你的另一个问题是strcat(fullstring,chunk); , you've no control in your loop that stops appending to this string if you happen to receive more data than it can hold. 如果您碰巧收到的数据多于可以容纳的数据,那么您的循环中无法控制停止附加到此字符串。 The size is also likely off by one, as you need room for the last nul terminator. 大小也可能是一个,因为你需要最后一个nul终结器的空间。 Make it at least char * fullstring = malloc(sizeof(char)*filesize + 1 ); 至少使它成为char * fullstring = malloc(sizeof(char)*filesize + 1 ); But your loop really needs to check that's it is not writing past the end of that buffer. 但是你的循环真的需要检查它是不是写在缓冲区的末尾。

As for adding a nul terminator to buf , the recv call returns how many bytes you've read, so if you've checked recv for errors, do buf[numbytes] = 0 , but this will be off by one as well, as you've allocated 10 bytes for buf and you try to read 10 bytes into it as well - but in C, a string needs room for a nul terminator too. 至于为buf添加一个nul终结符,recv调用返回你读取的字节数,所以如果你已经检查了recv的错误,那么执行buf[numbytes] = 0 ,但这也会被一个buf[numbytes] = 0关闭,如同你为buf分配了10个字节,你也尝试读取10个字节 - 但是在C中,字符串也需要空间来容纳nul终结符。 Make buf 11 bytes big. 使buf 11字节大。 Or recv() only 9 bytes. 或者recv()只有9个字节。

In fact, you're off by one many places, so start counting how many bytes you need, and were you put stuff into them. 事实上,你离开了很多地方,所以开始计算你需要多少字节,然后把东西放进去。 Remember that in C, arrays starts with index zero, and an array of 10 can only be indexed by index 0 to 9. 请记住,在C中,数组以索引0开头,而数组10只能由索引0到9索引。

This (line 93) is suspect: 这(第93行)是可疑的:

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

UPDATE This (line 99,100) is also wrong: 更新此(第99,100行)也是错误的:

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

UPDATE2: The buffer is too small UPDATE2:缓冲区太小

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

UPDATE3: UDP is unreliable. UPDATE3:UDP不可靠。 Transmission of a packet may fail (packets may be dropped anywhere between sender and receiver) , and the packets may be received in a different order than in which you sent them. 数据包的传输可能会失败(数据包可能会丢弃在发送方和接收方之间的任何位置),并且可能会以与发送数据包不同的顺序接收数据包。

Well, it shouldn't be a problem on modern OS:es but you don't check the returned value from malloc() for NULL. 好吧,它应该不是现代操作系统的问题:但是你不检查malloc()的返回值是否为NULL。 On what line does it crash and with what signal? 在什么线路上崩溃并发出什么信号?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM