C++如何正确释放内存?

3
int main(){
    int *a = new int[5];
    int *b = new int[10];
    int *c;
    for (int i = 0; i < 5; ++i){
        a[i] = i * i;
    }
    for (int i = 0; i < 10; ++i){
        b[i] = 50;
    }
    c = a;
    a = b;
    delete[]b;
    delete[]c;
    return 0;
}

在上述代码执行后,原本指向的内存a是否已被释放?
如果没有,应该如何正确释放?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
指针a必须保留给其他用途,因此禁止直接删除a。
这段代码的目的是通过a访问原本属于b的内存,并正确释放a原来占用的内存。

1
是的,你可以通过 c 来删除 a 的内存。 - Hatted Rooster
为什么不直接删除 ab 呢?这样会省去很多麻烦。 - byxor
即使是这个微不足道的例子,一眼就很难100%验证。通常的建议当然是避免使用原始指针而使用智能指针;如果不可能或者不希望这样做,我会将原始分配的地址存储在一个不会被覆写的地方。释放操作只通过这些变量进行。可以使用指针的vector来实现这一点。因此实现起来会看起来很像智能指针(例如,你可能希望有引用计数)。 - Peter - Reinstate Monica
6个回答

2

是的,内存已被释放。但是,当更改指针指向的内容时,请非常小心,因为这很容易导致内存泄漏。


1

它已经被释放。

因为在 c = a; 后,c 持有原本指向 a 的内存地址。而你通过 delete [] c; 释放了 c

// Assume originally a -> 1, b -> 2

c = a;  // Now a -> 1, b -> 2, c -> 1
a = b;  // Now a -> 2, b -> 2, c -> 1

你可以释放ab中的至少一个,它们指向同一内存块。你必须释放c

1
是的,它已经发生了。指针是普通变量,恰好包含地址。由于a被分配给c,因此您的第一个分配被释放。

1
在上面的代码执行后,原本指向的内存"a"已经被释放了吗?
是的,内存已经被释放。由于"c=a",所以"delete [] c;"会清除"a"的内存。
然而,你不需要使用"*c"来清除内存,直接删除"a"和"b"即可。
delete[]a;
delete[]b;

更新

由于您已编辑了您的答案,现在更清楚了您想要实现的目标,即通过a访问由b指向的内存,但在此之前您想要释放由a指向的内存。因此,以下是您需要做的:

1- 首先释放由a指向的内存。

delete []a;

2- 现在将a指向b所指向的内存位置

a=b;

现在,原先由a指向的内存位置被清除了,a现在指向b所指向的位置。

注意:请记住,现在当您将ab都指向相同的内存位置时,如果使用delete []adelete []b,则指向ab的内存位置都将被清除。


访问由指针a指向的内存b是否有效? - Ruby Sapphire
只要“b”指向某个内存位置,它就是有效的。在清除“b”所指向的内存后,您无法通过指针“a”访问“b”所指向的内存。 - Yousaf

0

在我看來,當你把delete視為不是對指針本身進行操作,而是對其指向的對象進行操作,就可以避免很多混淆。被刪除的不是指針,而是數組。請看以下例子,它與你的代碼非常相似:

struct Foo { 
     int id; 
     Foo(int i) : id(i) {} 
}; 
Foo* a = new Foo(1);
Foo* b = new Foo(2);
Foo* c;
c = a;
delete c;
c = b;
delete c;

delete c; 唯一的影响是我们之后不能对 c 进行解引用,但被删除的是先有 id 1Foo 对象,然后是有 id 2 的对象。


0

另一种方法是,可以考虑优化。也许在这里不需要分配内存。 看看这个案例

int a[5];
int b[10];

int func(int param) {
    for (int i = 0; i < 5; ++i){
        a[i] = i * i;
    }
    for (int i = 0; i < 10; ++i){
        b[i] = 50;
    }
}

int main(){
    for (int i = 0; i < 10000; ++i){
        func(i);
    }
    return 0;
}

在每次迭代中,您不需要分配/释放内存。但是,如果您有多线程,则会变得更加复杂。

使用类似的方法,我大大提高了科学项目中计算速度。

您的代码应该清晰易懂。考虑一下接替你的人是谁。如果在可读性和速度之间做出选择,应该选择可读性。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接