在c中重新分配结构

问题描述 投票:2回答:4

所以我尝试做的是为结构动态分配内存。结构如下所示:

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

c memory struct dynamic-memory-allocation realloc
4个回答
2
投票

你重新分配sizeof(CITY*)

这应该是sizeof(CITY),否则你分配指针的大小。

如果cityListCITYs的一个poinet的数组,这不会是一个问题,但从你的代码我不认为你接下来为每个CITY分配内存。所以citylist显然是一系列的CITYs。

因为您假设realloc为您的结构提供了存储空间,所以您开始使用数据填充它。这将覆盖堆,导致程序在下次调用realloc时中止,因为realloc现在可以在损坏的堆上运行。


1
投票

在realloc中,您使用sizeof(CITY *)。在我看来,你试图获得CITY结构的大小。所以你的代码不会这样做。

CITY *的大小是持有CITY结构的指针的大小,它基于您的系统体系结构(64位或32位)。这样,CITY的内容无法在重新分配之间传递,导致内存缓冲区覆盖并使应用程序崩溃。

如果你需要CITY结构的大小,只需使用sizeof(CITY)


1
投票

你犯了一个常见的错误,就是为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标准),所以周围的程序可以处理它。


-1
投票

假设您只想重新分配一个指针数组(到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
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.