【问题标题】:C malloc crashing only on second callC malloc 仅在第二次调用时崩溃
【发布时间】:2012-05-18 04:43:25
【问题描述】:

我在调用 malloc 时遇到了一些问题。问题是这个调用是在一个我在我的程序上调用两次的函数上进行的。 该函数的第二个 malloc 仅在我第二次调用此函数时崩溃。我尝试交换其中一些的顺序,甚至删除一个。在第一种情况下,第二个 malloc(最初是第一个)崩溃了,在第二种情况下,它崩溃了稍后出现在同一函数中的 realloc。此外,我尝试在第二次之前调用我的函数一次,并在(新的)第二次调用时一直崩溃。谁能帮我?这是我的代码:

int main(int argv, char *argc[]){
    fsys = malloc(sizeof(struct ext2system)); // Global pointer var

    getsysdata();

    list_dir(fsys->root);
//  list_dir(fsys->root); // IF THIS LINE IS UNCOMMENTED, 
                          // THE PROGRAM CRASHES ON THIS CALL
                          // IF NOT, IT CRASHES ON data = get_cont(fsys->root); 

    pdir dir = malloc(sizeof(struct s_direct));
    int* data;
    int offs, i;


    data = get_cont(fsys->root);  
    offs = 0;
    for (i = 0; i < fsys->root->i_links_count + 2; ++i) {
        offs += readdirent(getblock(data[0])+offs, dir);
        printf("%.*s\n", dir->name_len, dir->name);
        if(dir->file_type==1) printf("%s\n", data);
    }

    unmap(fsys->diskmap);
    return 0;
}

void list_dir(pinode inod){
    // Lists a directory contents
    pdir dir = malloc(sizeof(struct s_direct));
    int* data;
    int offs, i;

    data = get_cont(inod);
    offs = 0;
    for (i = 0; i < inod->i_links_count + 2; ++i) {
        offs += readdirent(getblock(data[0])+offs, dir);
        printf("%.*s\n", dir->name_len, dir->name);
    }

}

int *get_cont(pinode inod){
    // Recupera contenido de los blocks de datos de un inodo
    int *cont=NULL; 
    int *idx=NULL;
    int i=0;
    int *block;

    cont = malloc(sizeof(int));
    idx  = malloc(sizeof(int)); // HERE IS WHERE THE PROGRAM CRASHES
                                // EVEN IF MALLOCS ARE SWAPPED

    while(i < inod->i_blocks && i<13) {
        // Recupera los 12 primeros bloques directamente
            realloc(cont, i*sizeof(int)); // CRASHED HERE WHEN
                                          // I DELETED ONE MALLOC

            cont[i]=inod->i_block[i];
            i++;
    }

    if(i < inod->i_blocks){
        *idx=13;
        block=(int*)getblock(inod->i_block[*idx]);
        fetchcont(block, idx, cont, inod->i_blocks, 0);
    }
    if(i < inod->i_blocks){
        block=(int*)getblock(inod->i_block[*idx]);
        fetchcont(block, idx, cont, inod->i_blocks, 1);
    }
    if(i < inod->i_blocks){
        block=(int*)getblock(inod->i_block[*idx]);
        fetchcont(block, idx, cont, inod->i_blocks, 2);
    }

    return cont;

}

感谢您的建议!

【问题讨论】:

  • 尝试通过 valgrind 运行您的代码
  • 为什么甚至分配了 idx 而不仅仅是一个 int?
  • 使用调试器将帮助您解决问题。那么你就不需要像我们这样依赖随机数来做你的工作了。
  • 第一次调用 realloc 时,i 将为零,因此您将重新分配为 0 个字节。
  • @TimothyJones, pdir 定义如下: typedef struct s_direct *pdir;它是在 上声明的指向 s_direct 的指针

标签: c crash malloc call


【解决方案1】:

这部分肯定有问题(简称sn-p):

int i = 0;

cont = malloc(sizeof(int)); 

while(i < inod->i_blocks && i<13) {

        realloc(cont, i*sizeof(int)); 

第一次通过时,i 在 realloc 调用时将为零。 malloc() 手册页说:

realloc() 将 ptr 指向的内存块的大小更改为 size 字节。内容将不变为新旧尺寸中的最小值;新分配的内存将未初始化。如果 ptr 为 NULL,则对于所有 size 值,调用等效于 malloc(size)如果 size 等于 0,并且 ptr 不为 NULL,则调用 等价于free(ptr) 除非 ptr 为 NULL,否则它一定是由先前对 malloc()calloc()realloc() 的调用返回的。如果指向的区域被移动,则完成free(ptr)

既然你走了:

cont[i]=inod->i_block[i];

您将写入刚刚释放的内存(或者,当i 不为零时,您将写入刚刚分配的内存)。这可以是任何东西 - 您可能正在覆盖 malloc() 的内部结构,这可能会在稍后调用 malloc 或 free 时导致崩溃。

另外,在realloc(cont, 0) 之后,cont 将不再是malloc() 返回的指针(因为就像你写了free(cont);),它也不会为空。当i 为 1 时,这几乎肯定会崩溃。

你的意思可能是:

        realloc(cont, (i+1)*sizeof(int)); 

相反。

【讨论】:

  • 非常感谢!我测试了它并且它有效! (这是我之前没有意识到的这些时刻之一......)
【解决方案2】:

alloc 函数中的崩溃意味着您踩到了它们的簿记数据。在 getsysdata() 或 list_dir() 调用树中的某个位置,您通过一个错误的指针进行分配,该指针恰好指向超出您认为它指向的任何内容的末尾,从而损坏了 malloc 的数据。情况可能更糟,您的覆盖可能会踩到您关心的数据。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-05-27
    • 2015-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多