0

我已经在 main 中声明了双指针并像这样分配内存

char  **group_name;
group_name = realloc( NULL, 1);
group_name[0] = realloc(NULL ,20);

我已将此数组传递给一个函数,

group_count(object, count, group_name);

它使用 realloc。它工作正常,直到它填充前四个重新分配,但在第五个它给出错误。

libc detected *** ./textfileread.exe:  realloc(): invalid next size: 0x08643008

int group_count(struct friends obj[], char cn, char **grp_nm)
{
    int i=0,j=0;
    int grp_cn=0;
    char check=0;
    strcpy(grp_nm[0],obj[0].group);
    grp_cn++;
    grp_count++;

    for(i=1;i<cn;i++) {
        for(j=0;j<grp_cn;j++) {
            if(strcmp(grp_nm[j],obj[i].group)==0)
                check=1;
        }
        if(check==0) {  
            grp_cn++;
            grp_count++;
            printf("\t%d\n",grp_cn);
            grp_nm = realloc( grp_nm, grp_cn);   //at grp_cn=5 allocation gives error
            printf("\t%d\n",grp_nm);
            if(grp_nm == NULL) printf("\t%d\n",grp_cn);  // this 'if' didnt run, means no NULL return
            grp_nm[grp_cn-1] = realloc(NULL ,20);
            strcpy(grp_nm[grp_cn-1],obj[i].group);
        }
    check=0;
    }
}

printf("\t%d\n",grp_nm) 的输出;下面给出,在此之后的第五次重新分配迭代

2
140783624
3
140783624
4
140783624
5

*** glibc detected *** ./textfileread.exe: realloc(): invalid next size: 0x099c8008        ***
======= Backtrace: =========
/lib/i386-linux-gnu/libc.so.6(+0x6b961)[0x17b961]
lib/i386-linux-gnu/libc.so.6(+0x6f1ad)[0x17f1ad]
/lib/i386-linux-gnu/libc.so.6(realloc+0xe9)[0x180579]
./textfileread.exe[0x804934e]
./textfileread.exe[0x8048b42]
/lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xe7)[0x126e37]
./textfileread.exe[0x8048751]
======= Memory map: ========
00110000-0026a000 r-xp 00000000 08:02 1570626    /lib/i386-linux-gnu/libc-2.13.so

在屏幕上输出 5 之后,地址应该显示为 4 之后显示的那样。但它没有,那么为什么在 5 时它会出错?

4

4 回答 4

2

您的问题的核心可能是您破坏了 malloc 与新分配的块一起设置的簿记指针。当您将该“块”返回给 realloc 时,它会尝试使用损坏的指针在空闲区和其他类似活动中重新插入内存。

“为什么是 5 而不是 4”... 很可能是因为 realloc 在此之前不需要使用以前返回的块之一(例如,因为您的块实际上比您请求的要大,并且 realloc 认为您无需重新分配就可以了一些记忆)。malloc/free 是复杂的软件,误用时可能会表现出混乱行为。

于 2012-08-13T09:48:19.540 回答
1

为什么要realloc用于初始分配?

反正...

char  **group_name;
group_name = realloc( NULL, 1);
// group_name is now pointing to 1 byte of dynamically allocated memory
group_name[0] = realloc(NULL ,20);
// Whoops. Did we just write 4(or more bytes) into our 1 allocated byte?

我认为您的方法中存在相同的问题。

于 2012-08-13T05:35:37.173 回答
0

问题很可能是因为您在分配时使用了错误的大小。

char  **group_name;
group_name = realloc( NULL, 1);

但 achar **不是一个单字节,是四个或八个(取决于您是在 32 位还是 64 位平台上)。而是使用sizeof运算符:

group_name = realloc( NULL, sizeof *group_name);

稍后当您重新分配时:

grp_nm = realloc( grp_nm, grp_cn * sizeof *grp_nm);
于 2012-08-13T05:53:27.390 回答
0

谢谢。它有帮助。

   group_name = realloc( NULL, sizeof *group_name); 
    grp_nm = realloc( grp_nm, grp_cn * sizeof *grp_nm); 

在那个 libc 错误完成之后。但有时我无法在子程序中填充数组后读取值,即在 main() 中我无法读取值 group_name[3] 假设。但在子程序中 grp_nm[3] 显示得很好,因为我已经在子程序中将指针传递给数组 group_name。我发现的原因是,在重新分配期间,如果它与剩余内存冲突,它会将整个数组重新定义为新位置,从而将指针更改为数组。例如,在我将它传递给子程序之后,在主 group_name=0x5689F0 中,在第一次重新分配时 grp_nm=0x5689F0 在第二次重新分配时 grp_nm=0x5689F0

并且由于内存冲突导致数组grp_nm的位置发生一些重新分配后,将变为0x345FF1。所以我必须像这样从子程序中返回这个指针

     group_name=group_count(object, count, group_name);     

这样如果指针发生变化,它将立即更新 group_name=0x345FF1

于 2012-08-16T18:54:12.803 回答