重新分配一个数组,但不要丢失其中的元素

时间:2015-03-16 06:22:53

标签: c pointers malloc realloc

代码:

int * data;
data = malloc(sizeof(int)*10);
int i;
for(i=0;i<10;i++)
  data[i]=i;
int * aux;
aux = realloc(data,sizeof(int)*20);
if(aux)
   data=aux;
for(i=10;i<20;i++)
  data[i]=i;

一位老师曾告诉我“不,你不能用没有备份的元素重新分配数组”;我说,“哦,好的”,但现在对我来说毫无意义。

指针指向的内存已经分配,​​因此“不可能”丢失它;如果我安全realloc那就应该没问题。

我的问题是:如果我想调整动态数组的大小,上面的示例代码是否有效?

3 个答案:

答案 0 :(得分:3)

没关系。只需 两个 就可以完成另外三件事,

  1. 在使用返回的指针之前检查malloc()成功。
  2. 如果realloc()失败,则不应使用新维度访问数组。
  3. 在此代码块之后,很难确定data的已分配内存是否已更改(20)或未更改(10)。因此,更好的方法是不要检查not-NULL,

    • 检查NULL为realloc()
    • 的返回指针
    • 如果它为NULL则停止/返回/中止[或者如果可能则使用旧维度获取更多代码]
    • 继续使用新维度。

答案 1 :(得分:3)

您的代码并非完全有效。这是一个部分注释的修改版本:

size_t size = 10;  // Keep a record of the size of the array
int *data = malloc(sizeof(*data) * size);
if (data != 0)   // Always check that the allocation succeeds
{
    for (size_t i = 0; i < size; i++)
        data[i] = i;
    size_t new_size = size * 2;  // Grow arrays by doubling as a general rule
    int *aux = realloc(data, sizeof(*aux) * new_size);
    if (aux != 0)             // Test allocation - as you did anyway
    {
        data = aux;
        // Only initialize new data if successful
        for (size_t i = size; i < new_size; i++)
            data[i] = i;
        size = new_size;      // Record new size of array
    }
}

/* At this point, if data != 0, it is safe to access data[0]..data[size-1] */

您需要知道此片段末尾的数组有多大。在此版本中,如果data不为null,则size会记录其大小。 (如果数据为null,那么你现在可能应该放弃了。)在原始代码中,你不知道数组的大小。这是一个主要问题;如果您不知道它有多大,就不能安全使用阵列。

分配使用sizeof(*data),以便data的类型更改(比如double *data),malloc()语句的其余部分不必更改。这不是强制转换malloc()realloc()的结果。

答案 2 :(得分:0)

一切都很好。在重新分配失败的情况下,最初的两行代码(初始化新值)需要位于if语句中。否则,您将访问原始缓冲区,该缓冲区仅分配给10个元素,因此您最终将访问不属于您的内存。