标题是问题。
我仍然不太了解动态分配存储的行为。
#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;
}
每种情况下内存都会泄漏吗?
答案 0 :(得分:8)
案例1至3:无泄漏。
案例4和5;解除分配会导致未定义的行为。您正在从没有最初分配值的指针中删除。
为什么1到3没有泄漏?您将相应的delete
或delete[]
与已使用的new
或new[]
相匹配;并且它们成对匹配,每次分配一次解除分配。
我认为样本很简单,只是为了演示分配,但要注意指针不是&#34;重置&#34;到NULL
(或nullptr
),因此一旦取消分配,对先前分配的内存的任何访问都是未定义的。
std::move
上的旁注,是否会生成c3
指针nullptr
?不,它没有。 std::move
实际上&#34;移动&#34;任何事情,它只是更改了值类别,请参阅this answer和some sample code。
答案 1 :(得分:6)
案例4和5是未定义的行为,因此无法确定内存是否泄漏。
对于其他情况,内存不会泄漏。但是,值得指出的是,使用new
和delete
确实非常糟糕,您应该始终使用资源管理类来保存内存。或者更简单地说,你不应该首先提出这个问题。
答案 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中很好地解释了char
和new/delete
之间的差异。
在你的计划中:
new[]/delete[]