2011-05-29 203 views
2

我想动态地重新分配一个结构数组的内存(实际上是一个数组,每个结构都是2个,但是这里为了简单起见,这里是1),这个结构正在被读取/传输到一个文件或者被用户输入。Realloc一个结构数组

typedef Struct 
{ 
    char surname[21]; 
    char firstname[21]; 
    char username[21]; 
... 
} User; 

...在main():

int size = 0; /* stores no. of structs */ 
User* user_array = (User *) calloc(1, sizeof(User)); 
if(user_array == NULL) 
{ 
    printf("Cannot allocate initial memory for data\n"); 
    exit(1); 
} 
else 
    size++; 

我想,然后在需要时使用函数调用来增加阵列:

int growArray(User user_array*, int size) 
{ 
    User *temp; 
    size++; 
    temp = (User *) realloc(user_array, (size * sizeof(User)); 
    if(temp == NULL) 
    { 
     printf("Cannot allocate more memory.\n"); 
     exit(1); 
    } 
    else 
     user_array = temp; 
    return size; 
} 

不幸的是,realloc的永远不会奏效。两个结构体每个实例只有大约200个字节,并且将初始大小设置为10就可以正常工作,所以我尝试使用realloc的方式肯定有问题。

系统是Win 7 64,在运行Quincy(MinGW GUI)的4GB Core i5上。

+1

'INT growArray(用户user_array,INT大小)'?你错过了一个'*'吗? – kennytm 2011-05-29 19:41:25

+0

发布实际代码 - 这不会编译 – 2011-05-29 19:41:59

+0

@KennyTM我认为他错过了其中两个。 – cnicutar 2011-05-29 19:47:23

回答

3

您正在本地更改user_array的值。该函数返回时,该值将丢失。改为传递一个指向user_array指针的指针。

+1

和一个指针的大小太... – Neil 2011-05-29 19:57:18

+0

对不起,我忘了添加*到我的代码上面...它现在已经修复。 – thelionroars1337 2011-05-29 20:44:55

+0

谢谢 - 这是问题所在。我不明白,直到其他海报更具体地说明如何做到这一点。 – thelionroars1337 2011-05-30 09:36:38

6

realloc将由user_array指向的内存大小更改为指定大小,但不会按大小增加大小。鉴于你的函数被调用growArray,我会想你想让它通过size增加数组的大小,在这种情况下,你需要:

int growArray(User **user_array, int currentSize, int numNewElems) 
{ 
    const int totalSize = currentSize + numNewElems; 
    User *temp = (User*)realloc(*user_array, (totalSize * sizeof(User))); 

    if (temp == NULL) 
    { 
     printf("Cannot allocate more memory.\n"); 
     return 0; 
    } 
    else 
    { 
     *user_array = temp; 
    } 

    return totalSize; 
} 

注意growArray需要的user_array地址,原因因为这是realloc可能会移动内存,如果它不能扩展现有的块到所需的大小。

要使用它:

int size = 0; 
User* user_array = (User *) calloc(1, sizeof(User)); 
if(user_array == NULL) 
{ 
    printf("Cannot allocate initial memory for data\n"); 
    exit(1); 
} 

/* add 10 new elements to the array */ 
size = growArray(&user_array, size, 10); 
+0

当它传递给growArray时,Size等于数组中结构的数量(在它增加之前)。 growArray中的++的大小会将其增加到新的数字上(打算一次增加1个 - 从文件中的未知条目数量或用户添加),所以我相信size * sizeof(User)对此是正确的做法。我注意到你已经使用了双重间接运算符@cnicutar了,我仍然试图让我的头在那里发生的事情。这一定是我出错的地方......如果我不这样做,我仍然会使用user_array的旧开始地址? – thelionroars1337 2011-05-29 22:54:04

+1

是的,那可能是你的问题。'realloc'可能无法将现有的'user_array'指针内存块扩展到足够大的尺寸。如果发生这种情况,它会在其他地方分配一个**新**内存块,并从'user_array'上复制所有内容。返回值是新的内存位置。使用pointer-to-a-pointer允许'growArray'更新调用者的user_array的值,因为其先前的值现在是无效的。 – Node 2011-05-29 23:03:39