C中增长内存中的多维数组

Multidimensional array in growing memory in C

这是我的代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct{
char ipaddr[20];
char filename[2048];
}iplog;

int main(){
    unsigned long numrec=0;
    iplog* e=(iplog*)calloc(1,sizeof(iplog)+1);
    iplog* p=e;
    memcpy(e->ipaddr,"127.0.0.1",20);
    memcpy(e->filename,"/bla/bla/bla",2048);
    e=(iplog*)realloc(e,sizeof(iplog)*(numrec++)+1); //memory not growing?
    e++;
    memcpy(e->ipaddr,"192.168.1.2",20);
    memcpy(e->filename,"/abc/def/ghi",2048);
    for (*p;p;p++){
        printf("IP=%s, File=%s\n",p->ipaddr,p->filename);
    }
    free(e);
    return 0;
}

我想做的是在 RAM 中创建一个结构数组。我不能使用 array[n].element=value 格式,因为我不知道处理所有元素需要多少内存,所以我认为每次重新分配内存会有好处。当我引入 realloc 时,会发生分段错误。

这是我的逻辑,有错误的地方请指正。首先,我分配足够的内存 (via sizeof(iplog)) 加上一个字节给空字符。然后我将数据发送到结构的每个元素。没问题。

我将用于内存访问的原始分配指针在 realloc 内部使用,因此我不会使用它们自己的指针分配数百个新的内存块块。第二个参数的值足以 space 包含我需要的所有结构数据。我使用 numrec++ 来实现这一点。

然后我递增数据指针(通过 e++)以将数据写入内存中的新 space。

最后,我使用我第一次用来分配内存的原始指针来尝试遍历内存中的数据来打印它,但我看到的输出只是错误的行数分段错误如下:

IP=, File=
IP=, File=
...
...
IP=, File=
IP=, File=
Segmentation fault

我对上述代码的期望是:

IP=127.0.0.1, File=/bla/bla/bla
IP=192.168.1.2, File=/abc/def/ghi

我做错了什么?我假设它与 realloc 有关?

您的第一个问题是您对 numrec 的使用。你去调用realloc的时候,numrec是0,而你是post-递增,也就是说这里用0。您真正想要的是 numrec 在 realloc 之前为 1(因为此时您确实有 1 条记录),然后进行预递增 (++numrec),以便递增发生在评估之前并且应该以 2 的值结束。

第二个问题是您在分配中分配了一个额外的字节。当你去做指针运算时,这会把事情搞砸。当您执行 e++ 时,这将按结构的大小而不是分配的大小推进 e。这意味着您将在第二个结构之前结束 1 个字节。

最后一个问题是你的 for 循环。你应该做的是在这里使用 numrec 来控制你的循环。你现在拥有它的方式,你无缘无故地评估 *p,然后你循环直到 p 这与说直到 p != 0 相同,这不是你想要的。

e=(iplog*)realloc(e,sizeof(iplog)*(numrec++)+1);

相当于:

e=(iplog*)realloc(e,sizeof(iplog)*(numrec)+1);
numrec = numrec + 1;

由于numrec已经初始化为0,你在生效,使用:

e=(iplog*)realloc(e,1);

这就解释了分段错误的问题。

将该行更改为:

// You need to be able hold 2 iplog objects.
numrec = 1;
e = realloc(e,sizeof(iplog)*(++numrec)); // No need of the extra +1
                                         // No need of the explicit cast either.

阅读完所有评论和答案后,我现在设法让我的代码工作了。真正的问题是分配足够的内存。原来我之前只在我的realloc中分配了1个字节的内存。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct{
char ipaddr[20];
char filename[2048];
}iplog;

int main(){
    unsigned long numrec=1,n=0;
    iplog* op=(iplog*)calloc(1,sizeof(iplog)+1);
    iplog* p,*e=op;
    strcpy(e->ipaddr,"127.0.0.1[=10=]");
    strcpy(e->filename,"/bla/bla/bla[=10=]");
    op=(iplog*)realloc(op,sizeof(iplog)*(++numrec)+1); //memory not growing?
    e=op;e+=(numrec-1);
    strcpy(e->ipaddr,"192.168.333.444[=10=]");
    strcpy(e->filename,"/abc/def/ghi[=10=]");
    op=(iplog*)realloc(op,sizeof(iplog)*(++numrec)+1); //memory not growing?
    p=op;e=op;e+=(numrec-1);
    strcpy(e->ipaddr,"111.222.1.2[=10=]");
    strcpy(e->filename,"/abcc/defa/ghif[=10=]");
    for (n=0;n<numrec;n++){
        printf("IP=%s, File=%s\n",p->ipaddr,p->filename);
    p++;
    }
    free(op);
    return 0;
}


这看起来像零长度数组的情况。使用此数组,您可以在知道实际数组长度时分配所需的元素大小。

请参阅https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html