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

时间:2015-10-09 02:55:34

标签: c memory struct malloc realloc

这是我的代码:

#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内部,因此我不会使用自己的指针分配数百个新的内存块。第二个参数的值是足够的空间来包含我需要的所有结构数据。我使用numrec ++来实现这个目的。

然后我增加数据指针(通过e ++)将数据写入内存中的新空间。

最后,我使用我用来第一次分配内存的原始指针,尝试迭代内存中的数据进行打印,我看到的所有输出都是错误的行数和分段错误一起打印如下:

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有关?

4 个答案:

答案 0 :(得分:0)

您的第一个问题是您使用numrec。当你打电话给realloc时,numrec是0,你是后递增的,这里使用的是0。你真正想要的是numrec在重新分配之前是1(因为那时你有1条记录),然后做一个预增量(++numrec),以便在评估之前发生增量并且应该以2的值结束。

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

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

答案 1 :(得分: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.

答案 2 :(得分:0)

阅读完所有评论和回答后,我设法让我的代码现在正常工作。真正的问题是分配足够的内存。原来我之前只在我的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\0");
    strcpy(e->filename,"/bla/bla/bla\0");
    op=(iplog*)realloc(op,sizeof(iplog)*(++numrec)+1); //memory not growing?
    e=op;e+=(numrec-1);
    strcpy(e->ipaddr,"192.168.333.444\0");
    strcpy(e->filename,"/abc/def/ghi\0");
    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\0");
    strcpy(e->filename,"/abcc/defa/ghif\0");
    for (n=0;n<numrec;n++){
        printf("IP=%s, File=%s\n",p->ipaddr,p->filename);
    p++;
    }
    free(op);
    return 0;
}

答案 3 :(得分:0)


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

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