Invalid Free or corruption out

问题描述:

我是C新手,完全失去了这个问题。这是一项家庭作业,实现类似C中的pagerank算法。Invalid Free or corruption out

我想通过2D指针指针数组记录其他页面的链接。我的程序工作得很好,很高兴地为大量链接计算pagerank,但是,每当我尝试释放链接数组时,我都会收到“无效的免费”错误。

示例代码:

struct webpage { 
    char name[20]; 
    int links_out; 
    struct webpage **links_in; //to hold pointers to pages. 
    int index; //stores the position in the pre-sorted array 
      // as I have to print it out in this order 
}; 

static struct webpage *pages = NULL; 

这是我的数据结构。像的页(NPAGES)的数量的一些基本变量读取后我然后分配内存

pages = (struct webpage *)calloc(npages, sizeof(struct webpage)); 

正如我在每个网页读取I分配内部2D阵列links_in如下

pages[counter].links_in = (struct webpage **)calloc(npages, sizeof(struct webpage *)); 

,然后将每个页面里面:

for(i =0; i< npages; ++i) 
pages[counter].link_in[i] = (struct webpage *)calloc(1, sizeof(struct webpage)); 

我排序我的网页数组。然后阅读链接信息并用bsearch对我的数组进行二进制搜索以获得指向每个期望页面的指针。

struct webpage *temp_in; 
struct webpage *temp_out; 

temp_in = bsearch(temp_str, pages, npages, sizeof(struct webpage), struct_cmp_by_name); 
temp_out = bsearch(temp_str2, pages, npages, sizeof(struct webpage), struct_cmp_by_name); 

然后我给你

temp_in->links_in[temp_out->index] = temp_out; 

这一切的伟大工程,我能够访问所有需要的数据来计算的PageRank。 一旦我做了我尝试释放内存如下:

for(int i = 0; i < npages; ++i){ 
    for(int k = 0; k < npages; ++k){ 
    if(pages[i].links_in[k] != NULL){ 
      free(pages[i].links_in[k]); //this line is causing the error 
      pages[i].links_in[k] = NULL; 
    } 
    } 
free(pages[i].links_in); 
} 

呼叫到第k循环内罚球无效免费(或两次免费腐败了)错误的第一次它被调用。

我一直在gdb的代码和东西似乎指向正确的事情。 gdb列出该行作为程序中断点。

的valgrind说大同小异:

Invalid free()/delete/delete[] 
at 0x4A05187: free (vg_replace_malloc.c:325) 
by 0x4009C4: memory_dump (pagerank.c: 87) // this is the line free(pages[i].links_in[k]; 
by 0x4013F2: seq_check_condition (pagerank.c:355) 
by 0x40162F: main (pagerank.c:418) 

在任何时候,我那点之前删除/*是(或任何存储TBH)内存。

感谢您的任何建议。

+0

这不能回答你的问题,但你有排序你的数组? – phoxis 2011-05-19 12:55:50

+0

在读入所有页面之后但在定义链接之前对数组进行排序 – raf 2011-05-19 13:03:58

+0

好的phoxis是正确的。我不应该为内部数组分配内存。我只需要页面[i] .links_in的calloc。 – raf 2011-05-19 13:48:31

我想是因为每个页面您分配一个新的webpage指针,你并不需要做以下

for(i =0; i< npages; ++i) 
    pages[counter].link_in[i] = (struct webpage *)calloc(1, sizeof(struct webpage)); 

这是。 pages[counter].link_in[i]用于保存指向webpage的指针,即。它应该指向一个已经存在和分配的页面。所以你只需要分配那个webpage实例的地址。

我认为这个问题是在这里:

更改您的验证码

for(int i = 0; i < npages; ++i){ 
    for(int k = 0; k < npages; ++k){ 
    if(pages[i].links_in[k] != NULL){ 
      free(pages[i].links_in[k]); //this line is causing the error 
      pages[i].links_in[k] = NULL; 
    } 
    } 
free(pages[i].links_in); 
} 

要这样:

for(int i = 0; i < npages; ++i){ 
    free (pages[i].links_in); 
} 
free (pages); 

这是因为pages[i].links_in[x]持有环节都指针到一些pages[j],并且因为一个特定的pages[j]地址可能发生在pages[i].links_in[x]对于任何数量的i,因此潜在地址pages[j]发生在多个地方,试图通过您的例程在行free(pages[i].links_in[k]);中释放。

请让我们知道这是否有帮助。

+0

如果根据答案的第二部分更改我的代码,错误消失,但分配给链接[k]的内存将丢失。我会尝试做出你建议的第一个改变。 – raf 2011-05-19 13:40:14

+0

应该没有内存泄漏,前提是你也可以按照我的答案的第一部分,不要分配'webpage'结构。这是因为您正在使用'link_in'指向*现有内存位置,因此您不需要分配新的内存副本。相反,通过执行'calloc'(我在回答中突出显示)会导致内存泄漏。我会建议您对代码进行进一步研究。 – phoxis 2011-05-19 13:56:33

我的猜测是,这是问题:

temp_in->links_in[temp_out->index] = temp_out; 

看来你已经分配的内存为所有的“links_in”指针 - 那么你改变这种指针指向的内存另一位你已分配。

也许你想是这样的:

memcpy(temp_in->links_in[temp_out->index], temp_out, sizeof(struct webpage)); 

...还是有点重新设计的?

+0

确实很奇怪。我做了这个改变,我得到了一个seg-fault。这两个变量的大小都在struct网页的大小范围内。 – raf 2011-05-19 13:08:50

+0

复制整个网页结构不是我想的好主意,相反,指向该网页的指针会更好。 – phoxis 2011-05-19 13:36:20

看起来像pages[i].links_in[k]应该是pages[i].link_in[k]