malloc内存损坏,fopen

malloc内存损坏,fopen,c,sockets,udp,malloc,fopen,C,Sockets,Udp,Malloc,Fopen,我尝试过使用GDB和Valgrind,但我似乎无法找出问题所在。 有趣的是,程序在正常执行和GDB期间崩溃,而不是Valgrid 为了帮助您理解代码,以下是程序的基本要点: 通过套接字和UDP与服务器通信以传输文件,并处理一些基本的数据包丢失 我不会共享服务器的代码,因为我知道问题不存在。 有一点可能会让一些人感到困惑,那就是我自己用一个数字生成器实现了数据包丢失。现在除了让程序使用另一个recvfrom之外,它实际上什么也做不了 为了指导您完成程序输出,客户机告诉服务器它想要什么文件,服务器告

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

为了帮助您理解代码,以下是程序的基本要点: 通过套接字和UDP与服务器通信以传输文件,并处理一些基本的数据包丢失

我不会共享服务器的代码,因为我知道问题不存在。 有一点可能会让一些人感到困惑,那就是我自己用一个数字生成器实现了数据包丢失。现在除了让程序使用另一个recvfrom之外,它实际上什么也做不了

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

输出显示发送的块、接收的字符数以及连接的字符串

据我所知,文件传输成功了,这正是我用来写入接收到的文件的fopen调用给我带来的麻烦。我不确定这是否与我的malloc电话有关

以下是源代码:

pastebin.com/Z79hvw6L

以下是CLI执行和Valgrind的输出(GDB似乎没有提供更多信息):

请注意,CLI给出了malloc内存损坏错误,而Valgrind没有

CLI:

瓦尔格林:

谢谢你的帮助

添加了GDB回溯结果

======= 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]

也许这可以让人了解程序的哪个部分出错了

好吧,这在现代OS:es上应该不是问题,但是您不会检查malloc()返回的值是否为NULL。它在哪一条线上坠毁,发出什么信号

char chunk[10];
chunk[10] = '\0';
错误,块[10]是数组的一个过去部分

总的来说,做这件事要小心

char filename[25];
scanf("%s",filename);
如果您输入一个长文件名,您将丢弃内存。使用fgets()会更好。您至少还需要检查scanf是否成功,否则文件名上的以下strlen()无效

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

编辑。 另一个问题是strcat(fullstring,chunk),循环中没有控件,如果您碰巧接收到的数据超过了该字符串所能容纳的数量,则该控件将停止追加到此字符串。尺寸也可能减少1,因为您需要为最后一个nul终止符留出空间。使其至少
char*fullstring=malloc(sizeof(char)*filesize+1)但是你的循环确实需要检查它是否写过了缓冲区的末尾

至于将nul终止符添加到
buf
,recv调用将返回您读取的字节数,因此如果您检查了recv是否有错误,请执行
buf[numbytes]=0
,但这也将被禁用,因为您已为
buf
分配了10个字节,并尝试将10个字节读入其中-但在C中,字符串也需要为nul终止符留出空间。使buf 11字节变大。或recv()仅为9个字节

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

这(第93行)是可疑的:

buf[strlen(buf)-1]='\0';
更新此项(第99100行)也是错误的:

char chunk[10];
chunk[10] = '\0';
UPDATE2:缓冲区太小

char * fullstring = malloc(sizeof(char)*filesize); // line 103
...
strcat(fullstring,chunk); // line 124
更新3:
UDP是不可靠的。数据包的传输可能会失败(数据包可能会在发送方和接收方之间的任何位置丢弃),并且数据包的接收顺序可能与发送顺序不同。

通常,如果您无法在发布上下文中发布相关的源子集,你不会得到太多的回复。为什么不把它在valgrind崩溃的地方的回溯贴出来呢?我敢打赌,如果你得到回溯,然后在损坏的内存(崩溃点)上设置一个内存观察点,这将导致你的问题。你是什么意思?“我认为问题出在哪里?@dbeer,除非我误解了valgrind的输出,否则它在valgrind中根本不会崩溃。”backtrace补充道。我一直在观察我的绳子,它能容纳所有的块,结果似乎很好。就在fopen崩溃了。更改了块[10]位,但没有结果。我将文件名保持原样,一旦工作正常,我将进行错误检查。如果我知道buf不会以null结尾,那么我如何在没有strlen的情况下向它添加null终止符呢?谢谢,答案是我在整个字符串和块上越界了。我必须按照您的建议增加fullstring,并正确地终止每个块。我将研究解决其他问题。它在fopen上崩溃,我如何知道它崩溃的信号是什么?它说Malloc-内存损坏,如果你是这个意思的话。