Valgrind:无效读取大小4 – > sigsegv,没有valgrind和视觉工作室工作正常

我已经实现了一种压缩算法(使用霍夫曼编码),它使用节点的优先级队列(我定义的结构)。 现在,当我在linux或visual studio中运行代码时,一切正常。 当我检查visual studio中的内存泄漏时,没有给出。

现在的问题是,当我使用valgrind分析我的程序时,它终止于信号11(sigsegv)。 遇到的第一个错误是方法delete min中的“无效读取大小4”。 之后的其他错误是:Adress在大小为453的块中释放0字节,无效写入大小4,无效释放,删除或重新分配。

任何人都可以给我一些关于我可能犯的错误的建议吗? 我一直在互联网上搜索几个小时,但找不到我做错了什么(特别是因为它在没有使用valgrind时才起作用)。 或者提示如何调试并找出导致读取错误的原因。

非常感谢!

这是代码,以防有人想要查看它,但我想这并不是那么容易潜入这个特定的代码。

我猜它与代码的优先级队列有关:

我做霍夫曼部分的部分 – >每次删除2个最小节点并将两者的总和作为一个节点添加。

while(queue->size > 1){ node* n1 = delete_min(queue); node* n2 = delete_min(queue); // all the errors are encountered in this call node* temp = (node*) calloc(sizeof(node),1); temp->amount = n1->amount + n2->amount; insert_node(queue,temp); n1->parent = temp; n2->parent = temp; temp->left = n1; temp->right = n2; } 

以下是优先级队列的delete_min和insert_node方法:

 void insert_node(priority_queue* p_queue, node* x){ int i = p_queue->size; if(i == 0){ p_queue->queue = (node**) malloc(sizeof(node*)); } else{ p_queue->queue = (node**) realloc(p_queue->queue,sizeof(node*)*(p_queue->size+1)); } p_queue->queue[p_queue->size] = x; while(i>=0 && p_queue->queue[i]->amount 

queue[(i-1)/2]->amount){ node* temp = p_queue->queue[i]; p_queue->queue[i] = p_queue->queue[(i-1)/2]; p_queue->queue[(i-1)/2] = temp; i = (i-1)/2; } p_queue->size++; } node* delete_min(priority_queue* p_queue){ node** queue = p_queue->queue; node* min = queue[0]; if(p_queue->size>1){ int r = 0; int current = 1; //left child of root queue[0] = queue[p_queue->size-1]; queue = (node**) realloc(queue,sizeof(node*)*(--p_queue->size)); while(current

size){ //in case of 2 children, check if current needs to be right or left child if(current

size-1 && queue[current] > queue[current+1]){ current++; } if(queue[current] size--; } return min; }

编辑:添加了valgrind输出:

 Invalid read of size 4 ==1893== at 0x80498E0: delete_min (huffman.c:331) ==1893== by 0x80492DA: huffman_encode (huffman.c:196) ==1893== by 0x8049DDE: encode_file (main.c:94) ==1893== by 0x8049BBE: main (main.c:32) ==1893== Address 0x441d9a8 is 0 bytes inside a block of size 452 free'd ==1893== at 0x402BC70: realloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) ==1893== by 0x8049922: delete_min (huffman.c:335) ==1893== by 0x80492CC: huffman_encode (huffman.c:195) ==1893== by 0x8049DDE: encode_file (main.c:94) ==1893== by 0x8049BBE: main (main.c:32) ==1893== ==1893== Invalid read of size 4 ==1893== at 0x8049901: delete_min (huffman.c:333) ==1893== by 0x80492DA: huffman_encode (huffman.c:196) ==1893== by 0x8049DDE: encode_file (main.c:94) ==1893== by 0x8049BBE: main (main.c:32) ==1893== Address 0x441db64 is 444 bytes inside a block of size 452 free'd ==1893== at 0x402BC70: realloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) ==1893== by 0x8049922: delete_min (huffman.c:335) ==1893== by 0x80492CC: huffman_encode (huffman.c:195) ==1893== by 0x8049DDE: encode_file (main.c:94) ==1893== by 0x8049BBE: main (main.c:32) ==1893== ==1893== Invalid write of size 4 ==1893== at 0x8049906: delete_min (huffman.c:333) ==1893== by 0x80492DA: huffman_encode (huffman.c:196) ==1893== by 0x8049DDE: encode_file (main.c:94) ==1893== by 0x8049BBE: main (main.c:32) ==1893== Address 0x441d9a8 is 0 bytes inside a block of size 452 free'd ==1893== at 0x402BC70: realloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) ==1893== by 0x8049922: delete_min (huffman.c:335) ==1893== by 0x80492CC: huffman_encode (huffman.c:195) ==1893== by 0x8049DDE: encode_file (main.c:94) ==1893== by 0x8049BBE: main (main.c:32) ==1893== ==1893== Invalid free() / delete / delete[] / realloc() ==1893== at 0x402BC70: realloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) ==1893== by 0x8049922: delete_min (huffman.c:335) ==1893== by 0x80492DA: huffman_encode (huffman.c:196) ==1893== by 0x8049DDE: encode_file (main.c:94) ==1893== by 0x8049BBE: main (main.c:32) ==1893== Address 0x441d9a8 is 0 bytes inside a block of size 452 free'd ==1893== at 0x402BC70: realloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) ==1893== by 0x8049922: delete_min (huffman.c:335) ==1893== by 0x80492CC: huffman_encode (huffman.c:195) ==1893== by 0x8049DDE: encode_file (main.c:94) ==1893== by 0x8049BBE: main (main.c:32) ==1893== ==1893== Invalid read of size 4 ==1893== at 0x8049A0E: delete_min (huffman.c:337) ==1893== by 0x80492DA: huffman_encode (huffman.c:196) ==1893== by 0x8049DDE: encode_file (main.c:94) ==1893== by 0x8049BBE: main (main.c:32) ==1893== Address 0x0 is not stack'd, malloc'd or (recently) free'd ==1893== ==1893== ==1893== Process terminating with default action of signal 11 (SIGSEGV) ==1893== Access not within mapped region at address 0x0 ==1893== at 0x8049A0E: delete_min (huffman.c:337) ==1893== by 0x80492DA: huffman_encode (huffman.c:196) ==1893== by 0x8049DDE: encode_file (main.c:94) ==1893== by 0x8049BBE: main (main.c:32) 

第331行是delete_min中的行:node * min = queue [0];

编辑:

问题现在解决了。 在接受的答案中,解释了原因。 只需将重新分配的值分配正确,在delete_min中解决了所有问题。

 //realloc queue and assign new value to local queue var p_queue->queue = (node**) realloc(queue,sizeof(node*)*(--p_queue->grootte)); queue = p_queue->queue; 

我会向你解释第一个错误。

 ==1893== Invalid read of size 4 ==1893== at 0x80498E0: delete_min (huffman.c:331) ==1893== by 0x80492DA: huffman_encode (huffman.c:196) ==1893== by 0x8049DDE: encode_file (main.c:94) ==1893== by 0x8049BBE: main (main.c:32) 

在第331行,您可能正在读取(未签名的)int,在您尚未为自己的程序分配的内存中。

 ==1893== Address 0x441d9a8 is 0 bytes inside a block of size 452 free'd ==1893== at 0x402BC70: realloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) ==1893== by 0x8049922: delete_min (huffman.c:335) ==1893== by 0x80492CC: huffman_encode (huffman.c:195) ==1893== by 0x8049DDE: encode_file (main.c:94) ==1893== by 0x8049BBE: main (main.c:32) ==1893== 

这部分提供了有关您尝试阅读的内存部分的更多信息。 它说你已经使用了内存,但是reallox释放了它。 这意味着你正在从旧的指针读取你已经重新分配的内存部分。

您应该确保使用指针realloc返回,而不是旧指针。

在valgrind外部运行时不会崩溃的原因是,大多数情况下,内存的相同部分将由realloc分配。 因此指针保持不变,因此您的代码将起作用。 但是,有时,realloc将决定移动内存的一部分,然后您的代码将崩溃。 Valgrind试图警告你。

当您使用返回的指针时,其余的错误可能会得到解决。

根据您的Valgrind错误,您可能正在访问然后释放已删除的节点。 您应该考虑使用相应的行号(使用gcc中的-g编译)发布Valgrind错误,以便我们更方便地为您提供帮助。

编辑:最明显的错误,即segfault,是您应该开始调试的地方。 这一行失败了:

 while((2*i)+2 < p_queue->grootte-1 && (queue[i]->amount > queue[(2*i)+1]->amount || queue[i]->amount > queue[(2*i)+2]->amount)){ 

大概是因为queue是NULL。 为什么它是NULL? 可能是因为realloc没有分配任何东西。 为什么没有分配任何东西? 要么是因为内存不足(不太可能),要么是因为你试图分配大小为0的内容。(有关realloc的详细信息,请参阅http://www.cplusplus.com/reference/cstdlib/realloc/ )。 你怎么能要求0号? 如果p_queue->size-1为0。