所以我尝试做的是为结构动态分配内存。结构如下所示:
typedef struct{
char name[N];
int dimToys;
TOY toys[N];
}CITY;
我从.txt文件中读取了一些输入并将其复制到我的结构中。
然后我有一个函数,我想重新分配内存(并做一些其他不相关的东西),但我的程序只有在我一次使用这个函数时才能工作。如果我尝试多次重新分配内存,那么我的程序崩溃了。
它看起来像这样:
void next_city(CITY** cityList, *dimCities, otherstuff){
(*dimCities)++;
*cityList = realloc(*cityList, (*dimCities) * sizeof(CITY*));
otherstuff...
}
我尝试运行调试器,当我第二次调用该函数时,它会在realloc的行中崩溃。 main函数中函数的调用如下所示:
cityList = malloc(sizeof(CITY*));
for(...){
...
next_city(&cityList, &dimCities, otherstuff);
}
我已经尝试使用临时变量进行重新分配,然后将其复制到我原来的cityList
中,但它既不起作用也不起作用。
后期编辑:
因为很多人告诉我用一些澄清来更新我的问题,所以在我对你们告诉我的内容进行一些修改之后,我会更清楚地展示我的代码。
void next_city(char line[], CITY **cityList, int *dimCities){
(*dimCities)++;
*cityList = realloc(*cityList, (*dimCities) * sizeof(CITY)); //UPDATE CITYLIST DIMENSION
cityList[(*dimCities) - 1]->dimToys = 0;
char *word = strtok(line, " ");
strcpy((cityList[(*dimCities) - 1]->name), word); //INSERET NAME OF THE CITY
word = strtok(NULL, " ");
strcpy((cityList[(*dimCities) - 1]->toys[cityList[(*dimCities) - 1]->dimToys].toyType), word); //INSERT NAME OF THE TOY
}
int main(){
int nrPasi;
int dimCities = 0;
scanf("%d", &nrPasi);
fgetc(stdin);
int i;
CITY *cityList;
cityList = NULL;
char line[100];
for(i = 0;i < nrPasi;i++){
fgets(line, 100, stdin);
next_city1(line, &cityList, &dimCities);
}
return 0;
}
所以我基本上读了类似的东西
3
Berlin car
Berlin doll
Madrid jacket
我只是想逐步阅读它。现在我将CITY *与CITY切换后,realloc不会破坏我的程序,但当我尝试访问它时,它会发生在下一行。我得到了SISGEV
你重新分配sizeof(CITY*)
这应该是sizeof(CITY)
,否则你分配指针的大小。
如果cityList
是CITY
s的一个poinet的数组,这不会是一个问题,但从你的代码我不认为你接下来为每个CITY
分配内存。所以citylist
显然是一系列的CITY
s。
因为您假设realloc
为您的结构提供了存储空间,所以您开始使用数据填充它。这将覆盖堆,导致程序在下次调用realloc
时中止,因为realloc
现在可以在损坏的堆上运行。
在realloc中,您使用sizeof(CITY *)。在我看来,你试图获得CITY结构的大小。所以你的代码不会这样做。
CITY *的大小是持有CITY结构的指针的大小,它基于您的系统体系结构(64位或32位)。这样,CITY的内容无法在重新分配之间传递,导致内存缓冲区覆盖并使应用程序崩溃。
如果你需要CITY结构的大小,只需使用sizeof(CITY)
你犯了一个常见的错误,就是为CITY
指针分配空间而不是结构本身。你需要分配sizeof(CITY)
。
但还有其他几点要做......
cityList = NULL;//No need allocate anything up front.
dimCities=0u; //I'll assume this is size_t.
for(...){
...
if(next_city(&cityList, &dimCities /*, otherstuff*/)){
//There was an error. What to do now?
}
}
和
int next_city(CITY** cityList, size_t *dimCities/*, otherstuff*/){
(*dimCities)++;
CITY* newList = realloc(*cityList, (*dimCities) * sizeof(CITY));
if(newList==NULL){
//out of memory..
return 1;//Error return...
}
*cityList=newList;
otherstuff...
return 0;//Good return...
}
如果你将NULL
传递给realloc
,它的行为就像malloc()
。我不知道你如何处理错误,但如果没有足够的内存来重新分配realloc()
什么都不做,并返回NULL
。你预先分配一个对象的方式很好。但个人这种方式更清洁。分配至少一个CITY
可能适合您,因为您永远不需要处理cityList==NULL
。
如果这是一个简单的程序,你可能会放弃和exit()
此时。我已经返回了一个错误标志(事实上的C标准),所以周围的程序可以处理它。
假设您只想重新分配一个指针数组(到CITY),那么当我测试它时,以下工作。但正如上面提到的那样,也许你想拥有一个CITY数组,那么你也想为CITY分配内存。
#include <stdio.h>
#include <stdlib.h>
typedef struct{
char name[10];
int dimToys;
int toys[10];
} CITY;
void next_city(CITY *** cityList, int *dimCities) {
(*dimCities)++;
*cityList = realloc(*cityList, (*dimCities) * sizeof(CITY*));
}
main(){
CITY ** cityList;
int dimCities=0;
int i;
cityList = malloc(sizeof(CITY*));
printf("%p\n", (void *) cityList); // print out the address of the memory allocated
for (i = 0 ; i < 10; i++){
next_city(&cityList, &dimCities);
malloc(1); // malloc more data to force some fragmenation so that you can see that realloc does something interesting.
printf("%p\n", cityList); // print out the address of the reallocated memory
}
}