这是我的代码:
#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有关?
答案 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)
这看起来像零长度数组的情况。使用此数组,您可以在知道实际数组长度时分配所需的元素大小。