C-释放数组时指针数组会发生什么情况?

C-释放数组时指针数组会发生什么情况?,c,arrays,pointers,C,Arrays,Pointers,我目前正在用C语言编程,我正在创建一个指针数组。数组中包含的这些指针将持续整个程序 假设指针数组是数组A,然后创建另一个指针数组B,将数组A的一个元素放入数组B,然后释放数组A 数组B中的元素会发生什么情况?由于数组A已被释放,它将不再有效,还是仍然有效,因为实际指针在内存中仍然有效 谢谢 下面是我的代码的示例-- 现在,如果执行此操作,数组_b[0]会发生什么情况? int *a = malloc(10 * sizeof(int)); for (int i = 0 ; i != 10 ; i+

我目前正在用C语言编程,我正在创建一个指针数组。数组中包含的这些指针将持续整个程序

假设指针数组是数组A,然后创建另一个指针数组B,将数组A的一个元素放入数组B,然后释放数组A

数组B中的元素会发生什么情况?由于数组A已被释放,它将不再有效,还是仍然有效,因为实际指针在内存中仍然有效

谢谢

下面是我的代码的示例--

现在,如果执行此操作,数组_b[0]会发生什么情况?

int *a = malloc(10 * sizeof(int));
for (int i = 0 ; i != 10 ; i++) {
    a[i] = 2*i+1;
}
int *b = a;
free(a);
那么
b
也将无效

但是,如果你这样做

int *a = malloc(10 * sizeof(int));
for (int i = 0 ; i != 10 ; i++) {
    a[i] = 2*i+1;
}
int *b = malloc(10 * sizeof(int));
memcpy(b, a, 10 * sizeof(int));
free(a);

然后
b
保持有效。

C将数组解释为基元素的地址,因此根据释放数组的方式,可能根本没有释放该元素


但是,假设您释放了数组的所有元素,那么数组B中的指针仍将在那里(它仍将指向内存中的同一位置)。但是,您确实不知道该位置是什么,因为您已经释放了该位置的内存。您可能仍然会获得存储在那里的原始数据,或者它可能已被覆盖。但是使用它肯定不安全。

指针本身没有改变,它仍然指向它指向的地方。唯一的问题是,它指向的位置可能会分配给其他程序。您仍然可以使用未定义的行为写入和读取位置。检查此代码:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int *a = (int *)malloc(3 * sizeof(int));
    a[0] = 1, a[1] = 2, a[2] = 3;
    free(a);
    // a = NULL // if you add this, the following will crash.
    printf("%d\n", a[0]);
    printf("%d\n", a[1]);
    printf("%d\n", a[2]);
    return 0;
}
#包括
#包括
int main()
{
int*a=(int*)malloc(3*sizeof(int));
a[0]=1,a[1]=2,a[2]=3;
免费(a);
//a=NULL//如果添加此项,则以下内容将崩溃。
printf(“%d\n”,a[0]);
printf(“%d\n”,a[1]);
printf(“%d\n”,a[2]);
返回0;
}
如果幸运的话,你仍然可以得到正确的结果。但这只是运气


因此,通常在释放后将指针设置为
NULL
是个好主意。

所以不久前我刚刚了解了一点关于free()的知识,所以很抱歉,我还不太了解free(),但我只知道一点:

要将动态分配的内存返回给系统,可以使用free()函数。我的教授举了这样一个例子:

struct listNode *Bob;
Bob = &any instance of listNode;
free(Bob);

所以我相信B仍然有效,而A不再被引用。Java定期收集不再被引用的动态分配内存,并将其放入“垃圾”中。C不会这样做,这就是为什么我们使用free()。希望这有点帮助。我还在学习自己。好问题:)

这三行为三个整数声明内存,并初始化整数。如果您在函数外部执行此操作,您可以愉快地获取这些变量的地址并将它们存储在数组中

int a = 1;
int b = 2;
int c = 3;
但是,如果在函数(堆栈上)中声明上述三个变量,并获取它们的地址,并将这些地址存储在某个位置,那么就产生了(潜在的)悬空指针问题

这一行分配足够的内存来容纳三个指向int的指针(12或24字节)

现在将先前定义的变量a、b、c的地址存储到数组_a[]中

array_a[0] = &a;
array_a[1] = &b;
array_a[2] = &c;
int **array_b = (int **) malloc (sizeof (int *) * 100);
int ndx;
for(ndx=0; ndx<100; ++ndx)
    array_b[ndx] = malloc( sizeof(int) );
它要么完全无害,要么非常危险,取决于a、b、c的申报地点,例如

int** youfun()
{
    int a = 1;
    int b = 2;
    int c = 3;
    int **array_a = (int **) malloc (sizeof (int *) * 3);
    array_a[0] = &a;
    array_a[1] = &b;
    array_a[2] = &c;
    return(array_a); //very bad!
}

int a = 1;
int b = 2;
int c = 3;
int** mefun()
{
    int **array_a = (int **) malloc (sizeof (int *) * 3);
    array_a[0] = &a;
    array_a[1] = &b;
    array_a[2] = &c;
    return(array_a); //safe, but strange
}
为数组_b[]声明和分配空间,并保留单个内存位置类似于为int声明和分配一个指针数组

int **array_b = (int **) malloc (sizeof (int *) * 1);
下面的赋值将数组_a[0]的内容放置(这是变量a和&a的地址,从上面看),并且只与将&a存储在数组_a[0]中一样危险/无害

array_b[0] = array_a[0];
释放数组_a是无害的,因为数组_a中没有存储任何可能“泄漏”的内容,也不会影响数组_b[0],因为其中包含a、&a的地址

free(array_a);
假设你做了下面的事情

int **array_a = (int **) malloc (sizeof (int *) * 100);
int ndx;
for(ndx=0; ndx<100; ++ndx)
    array_a[ndx] = malloc( sizeof(int) );
现在假设你做了这两件事

array_b = array_a; //you just discarded the memory references at array_b[0..99] and array_b
free(array_a); //you just discarded array_a[0..99]
上述操作将泄漏数组_b、数组_b[0..99]指向的所有内存以及数组_a[0..99]处的所有内存,因为您只复制了数组_a的地址,而不是数组_a[0..99]处的地址

下面是如何复制在数组_a[0..99]上分配的内存

for(ndx=0; ndx<100; ++ndx)
    array_b[ndx] = array_a[ndx];

用于(ndx=0;ndx通常,从外到内分配,从内到外释放总是一个好主意。如果看不到代码,很难用更多细节回答您的问题。如果您尝试释放尚未分配的内容,您将得到一个错误。您的代码仍然很好。
&a
的值是从
数组复制的_a[0]
数组\u b[0]
,之后是
数组\u b[0]
不需要持续使用
数组a
。在我的示例中,我正在将指针从数组a复制到数组B,当数组a被释放时,这些指针不会被释放。这是否意味着我应该是安全的?@user2985902否。其他指针与a处于相同的状态。它们仍然指向
a
指向的位置。但是释放
a
操作在逻辑上释放
A
指向的位置。释放后,该位置不再属于您的程序。因此,所有指向不属于您的程序的位置的其他指针都将无效。它们也应设置为
NULL
。@user2985902如果您希望其他指针有效,请接受dasblinkenlight建议,allo分别为它们分配空间并执行memcpyy您只能使用
free()
malloc()或相关函数分配的内容
array_b = array_a; //discarded memory references at array_b[0..99], and array_b
array_b = array_a; //you just discarded the memory references at array_b[0..99] and array_b
free(array_a); //you just discarded array_a[0..99]
for(ndx=0; ndx<100; ++ndx)
    array_b[ndx] = array_a[ndx];