C语言 重新定位数组,但不要丢失其中的元素



代码:

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应该没有问题。

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

您的代码并不完全有效。 以下是部分注释的修改版本:

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记录其大小。 (如果数据为空,你现在可能应该已经纾困了。 在您的原始代码中,您不知道数组的大小。 这是一个主要问题;如果您不知道数组有多大,则无法安全地使用它。

分配使用sizeof(*data),因此如果data的类型发生变化(例如double *data),malloc()语句的其余部分不必更改。 这是不投射malloc()realloc()结果的优势。

关系。再做三件事就完美了,

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

    • 检查 NULL 作为返回的 realloc() 指针
    • 如果为 NULL,则停止/返回/中止 [如果可以,请使用旧维度进行进一步的代码]
    • 否则继续使用新维度。

基本上没问题。最后两行代码(用于初始化新值)需要位于 if 语句内,以防重新分配失败。否则,您将访问仅分配给 10 个元素的原始缓冲区,因此您最终将访问不属于您的内存。

相关内容

  • 没有找到相关文章

最新更新