C ++:在以下情况下内存是否会泄漏?

时间:2016-02-01 13:49:21

标签: c++ memory-leaks

标题是问题。

我仍然不太了解动态分配存储的行为。

#include <utility>
int main() {
    // Case 1:
    volatile char *c1 = new char; // I'm gonna make these volatile, so the compiler won't change the code.
    volatile char *d1 = c1;
    delete d1;
    // Case 2:
    volatile char *c2 = new char[4];
    volatile char *d2 = c2;
    delete []d2;
    // Case 3:
    volatile char *c3 = new char;
    volatile char *d3 = std::move(c3);
    delete d3;
    // Case 4:
    volatile char *c4 = new char[4];
    delete c4++;
    delete []c4;
    // Case 5:
    volatile char *c5 = new char[4];
    for (int i = 0; i < 4; ++i)
        delete c5++;
    return 0;
}

每种情况下内存都会泄漏吗?

4 个答案:

答案 0 :(得分:8)

案例1至3:无泄漏。

案例4和5;解除分配会导致未定义的行为。您正在从没有最初分配值的指针中删除。

为什么1到3没有泄漏?您将相应的deletedelete[]与已使用的newnew[]相匹配;并且它们成对匹配,每次分配一次解除分配。

我认为样本很简单,只是为了演示分配,但要注意指针不是&#34;重置&#34;到NULL(或nullptr),因此一旦取消分配,对先前分配的内存的任何访问都是未定义的。

std::move上的旁注,是否会生成c3指针nullptr?不,它没有。 std::move实际上&#34;移动&#34;任何事情,它只是更改了值类别,请参阅this answersome sample code

答案 1 :(得分:6)

案例4和5是未定义的行为,因此无法确定内存是否泄漏。

对于其他情况,内存不会泄漏。但是,值得指出的是,使用newdelete确实非常糟糕,您应该始终使用资源管理类来保存内存。或者更简单地说,你不应该首先提出这个问题。

答案 2 :(得分:1)

案例1:

volatile char *c1 = new char; 
volatile char *d1 = c1;
delete d1;

没有记忆泄漏。您正在为其分配内存和c1点。然后发生指针c1的副本(不是数据)。所以d1指向c1指向的同一个地方。然后,删除d1等于删除c1

案例2:

volatile char *c2 = new char[4];
volatile char *d2 = c2;
delete []d2;

与上面相同,不同之处在于您正在分配一系列内存并删除一系列内存。所以,没有泄漏。

案例3:

volatile char *c3 = new char;
volatile char *d3 = std::move(c3);
delete d3;

您首先为其分配一个内存和c3点。现在您调用了move操作。此move操作会将c3持有的地址移至d3,而不会对实际数据进行任何更改或移动或复制。之后,您删除了d3,它实际指向c3所指向的相同位置。所以,没有泄漏。

案例4&amp; 5 :未定义的行为,如其他答案所述。

答案 3 :(得分:1)

我认为您假设def start_time_filter(self, queryset, value): if value.isdigit(): return queryset.raw("select * from app_task WHERE TIME(`start_time`) >= '{0}';".format(value)) return queryset.none() 为个人new char[5]执行了5个单独new s。 (对我而言,似乎可以解释为什么你提出案例4和5)。

但事实并非如此;例如,char指向单个已分配存储块,该存储块(至少)足够大以容纳4 c4个。您无法删除它的各个部分,只能删除所有

C++ Super FAQ中很好地解释了charnew/delete之间的差异。

在你的计划中:

new[]/delete[]