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

Posted

技术标签:

【中文标题】C++如何正确释放内存?【英文标题】:C++ how to correctly free memory? 【发布时间】:2017-03-12 12:17:30 【问题描述】:
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访问原本属于b的内存,并正确释放a曾经拥有的内存。

【问题讨论】:

是的,你删除了ac的内存。 为什么不直接删除ab呢?它会让你头疼。 即使是这个微不足道的例子也很难一目了然地 100% 验证。一般建议当然是避免使用原始指针并使用智能指针;如果这是不可能的或不希望的,我会将原始分配的地址保存在不会被覆盖的地方。释放仅通过这些变量发生。为此,可以使用vectors 的指针。因此实现后,它开始看起来很像智能指针(例如,因为您可能想要引用计数)。 【参考方案1】:

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

【讨论】:

【参考方案2】:

是的。指针是恰好包含地址的普通变量。由于a被分配给c。您的第一个分配被释放。

【讨论】:

【参考方案3】:

释放了。

因为在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

【讨论】:

【参考方案4】:

上面的代码执行后,原来有内存“a” 指向被释放?

是的,内存已释放。如c=adelete [] c;清空a的内存。

不过,不需要*c清空内存,直接删除ab即可

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访问是否有效? @RubySapphire 只要b 指向某个内存位置,它就有效。清除b指向的内存后,无法通过指针a访问b指向的内存【参考方案5】:

恕我直言,当您将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 的对象。

【讨论】:

【参考方案6】:

另一种方式 - 您可以考虑优化。也许你不需要在这里分配内存。 看这个案例

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;

您不需要在每次迭代时分配/释放内存。但是如果你有多线程,那就有点复杂了。

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

您的代码应该对每个人都清楚。想想谁会追随你。如果在可读性和速度之间进行选择——应该选择可读性。

【讨论】:

以上是关于C++如何正确释放内存?的主要内容,如果未能解决你的问题,请参考以下文章

在c ++中删除和释放向量内存的正确方法(防止不同的内存相关错误)

在 C 或 C++ 中释放内存 [重复]

Java我可以主动去释放对象占的内存吗?可以的怎释放?

在 C 和 C++ 中如何分配和释放 *array* 内存?

如何正确释放与 getline() 函数相关的内存?

内存泄漏简析