【问题标题】:Realloc an array of Structs重新分配结构数组
【发布时间】:2011-09-04 10:14:25
【问题描述】:

我正在尝试为正在从文件读取/向文件读取或由用户输入的结构数组(实际上是一个数组,每个 2 个结构,但为了简单起见,此处包括 1 个)动态重新分配内存。

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,在具有 4GB 的 Core i5 上,运行 Quincy(MinGW GUI)。

【问题讨论】:

  • int growArray(User user_array, int size)?您是否缺少*
  • 发布真实代码 - 这不会编译
  • @KennyTM 我认为他错过了其中两个。
  • 如果你让它工作,你可以通过使用 growArray 进行初始分配来简化代码。另外,请注意,您的初始 calloc() 将初始化第一个条目,而随后的 realloc() 将使扩展区域未初始化。像 cnicutar 笔记一样,调用者看不到“size++”。
  • dantje - 目前我使用 size 作为我的返回值 - 抱歉漏掉了

标签: c arrays struct realloc


【解决方案1】:

reallocuser_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);

【讨论】:

  • 大小等于传递给growArray时数组中结构的数量(在增加之前)。 growArray 中的 size++ 会将其增加到新数字(打算一次增加 1 - 从文件中的未知条目数或通过用户添加)所以我相信 size * sizeof(User) 对此是正确的方法。我注意到您使用了@cnicutar 所使用的双重间接运算符,我仍在努力了解那里发生的事情。这一定是我出错的地方...如果我不这样做,我仍然会使用user_array的旧起始地址吗?
  • 是的,这可能是你的问题。 realloc 可能无法将现有的 user_array 指针内存块扩展为足够大以容纳新大小。如果发生这种情况,它会在其他地方分配一个 new 内存块,并从user_array 复制所有内容。返回值是新的内存位置。使用指向指针的指针允许growArray 更新调用者的user_array 的值,因为它之前的值现在无效。
【解决方案2】:

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

【讨论】:

  • 抱歉,我确实忘记在上面的代码中添加 *... 现在已修复。
  • 谢谢 - 这就是问题所在。直到其他海报更具体地说明如何做到这一点,我才明白。
猜你喜欢
  • 2019-02-02
  • 2014-05-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-15
  • 2018-06-28
  • 1970-01-01
相关资源
最近更新 更多