阵列重新初始化会导致内存泄漏吗?

SlL*_*Wre 2 c c99

我在 SO 上找到了一个答案,建议使用以下解决方案来重新初始化 c 中的数组。

int *foo = (int[]){1,2,3,4,5};
Run Code Online (Sandbox Code Playgroud)

我不确定这样的语法到底会做什么,我有几个问题:

如果我的数组是之前创建的,它会导致内存泄漏吗?

double *my_array = (double[]){1.1, 2.2, 3.3, 4.4, 5.5};

...

my_array = (double[]){-1.1, -2.2, -3.3}; // Do i need to call free(my_array) first?
Run Code Online (Sandbox Code Playgroud)

是否允许在函数调用中使用这种方法?

void foo(int *arr)
{
  arr = (int[]){-2, -7, 1, 255};
}

int main()
{
  int *my_array = (int[]){1, 2, 3};
  foo(my_array);
  
  if (my_array[2] != 1)
    return -1;
}
Run Code Online (Sandbox Code Playgroud)

概括:

  • 这种语法是否只是使用预定义的值在堆中分配新内存并返回指针?
  • 它会自动清除前一个指针中的所有内容吗?

Eri*_*hil 5

首先,声明int *foo创建foo了一个指针,而不是一个数组。

(int[]){1,2,3,4,5}是复合字面量。很少有充分的理由以这种方式设置指向复合文字的指针。

复合文字是自动管理的,因此您无需释放它们。如果复合字面量出现在任何函数之外,则它具有静态存储持续时间;它存在于程序的整个执行过程中。否则,它具有与它所在的块相关联的自动存储持续时间,并且当该块的执行结束时,它的内存保留将结束。如果在块执行结束后使用指针,则不应设置指向此类复合文字的指针。

在这段代码中:

void foo(int *arr)
{
  arr = (int[]){-2, -7, 1, 255};
}
Run Code Online (Sandbox Code Playgroud)

arr设置为指向复合文字,但arr只是一个函数参数。当函数返回时,它实际上不复存在。

在这段代码中:

int *my_array = (int[]){1, 2, 3};
  foo(my_array);
  
  if (my_array[2] != 1)
    return -1;
Run Code Online (Sandbox Code Playgroud)

foo被调用时,它的参数arr设置为值my_array。当arr被内改变foo,它不会影响my_arraymy_array仍将指向(int[]){1, 2, 3}. 这将是正确的,无论是否arr设置为指向复合文字、分配的内存或其他任何内容,:更改函数内的参数不会更改作为参数传递的内容。

要从函数中获取指针,您可以返回它,也可以传递一个指向指针的指针,以便函数具有指针的地址:

void foo(int **arr)
{
    *arr = (int []) { -2, -7, 1, 255 };
}

int main(void)
{
    int *my_array = (int []) { 1, 2, 3 };
    foo(&my_array);
    …
}
Run Code Online (Sandbox Code Playgroud)

但是, thenfoo会将其复合文字的地址放入函数结束后使用的指针中。在这种情况下,您应该调用malloc保留内存,然后将数据复制到分配的内存中。稍后,在程序处理完这些数据后,它会调用free释放内存。