删除指向指针的指针会导致内存泄漏吗?
Will delete the pointer to pointer cause the memory leak?
我有一个关于 C 风格字符串符号常量和动态分配数组的问题。
const char** name = new const char* { "Alan" };
delete name;
当我在 new
一段内存后尝试 delete name
时,编译器建议我使用 delete
而不是 delete[]
。我理解 name
仅存储指向唯一读取字符串的指针的地址。
但是,如果我只delete
指向指针的指针(即name
),字符串本身会不会导致内存泄漏?
正如上面的评论所指出的,您不需要管理“Alan”所在的内存。
让我们看看实际情况如何。
我修改了你的代码:
#include <iostream>
void test() {
const char** name;
name = new const char* { "Alan\n" };
delete name;
}
int main()
{
test();
}
然后我将它弹出到 godbolt 中,它显示了引擎盖下发生的事情。 (摘录如下)
无论是clang还是gcc,存放“Alan\n”的内存都是静态内存,所以一直存在。这就是它不会造成内存泄漏的原因,即使您在提及它之后再也没有接触过它。 “Alan\n”指针的值只是程序内存中的位置,offset .L.str
或OFFSET FLAT:.LC0
.
clang:
test(): # @test()
push rbp
mov rbp, rsp
sub rsp, 16
mov edi, 8
call operator new(unsigned long)
mov rcx, rax
movabs rdx, offset .L.str
mov qword ptr [rax], rdx
mov qword ptr [rbp - 8], rcx
mov rax, qword ptr [rbp - 8]
cmp rax, 0
mov qword ptr [rbp - 16], rax # 8-byte Spill
je .LBB1_2
mov rax, qword ptr [rbp - 16] # 8-byte Reload
mov rdi, rax
call operator delete(void*)
.L.str:
.asciz "Alan\n"
gcc:
.LC0:
.string "Alan\n"
test():
push rbp
mov rbp, rsp
sub rsp, 16
mov edi, 8
call operator new(unsigned long)
mov QWORD PTR [rax], OFFSET FLAT:.LC0
mov QWORD PTR [rbp-8], rax
mov rax, QWORD PTR [rbp-8]
test rax, rax
je .L3
mov esi, 8
mov rdi, rax
call operator delete(void*, unsigned long)
我有一个关于 C 风格字符串符号常量和动态分配数组的问题。
const char** name = new const char* { "Alan" };
delete name;
当我在 new
一段内存后尝试 delete name
时,编译器建议我使用 delete
而不是 delete[]
。我理解 name
仅存储指向唯一读取字符串的指针的地址。
但是,如果我只delete
指向指针的指针(即name
),字符串本身会不会导致内存泄漏?
正如上面的评论所指出的,您不需要管理“Alan”所在的内存。 让我们看看实际情况如何。
我修改了你的代码:
#include <iostream>
void test() {
const char** name;
name = new const char* { "Alan\n" };
delete name;
}
int main()
{
test();
}
然后我将它弹出到 godbolt 中,它显示了引擎盖下发生的事情。 (摘录如下)
无论是clang还是gcc,存放“Alan\n”的内存都是静态内存,所以一直存在。这就是它不会造成内存泄漏的原因,即使您在提及它之后再也没有接触过它。 “Alan\n”指针的值只是程序内存中的位置,offset .L.str
或OFFSET FLAT:.LC0
.
clang:
test(): # @test() push rbp mov rbp, rsp sub rsp, 16 mov edi, 8 call operator new(unsigned long) mov rcx, rax movabs rdx, offset .L.str mov qword ptr [rax], rdx mov qword ptr [rbp - 8], rcx mov rax, qword ptr [rbp - 8] cmp rax, 0 mov qword ptr [rbp - 16], rax # 8-byte Spill je .LBB1_2 mov rax, qword ptr [rbp - 16] # 8-byte Reload mov rdi, rax call operator delete(void*) .L.str: .asciz "Alan\n"
gcc:
.LC0: .string "Alan\n" test(): push rbp mov rbp, rsp sub rsp, 16 mov edi, 8 call operator new(unsigned long) mov QWORD PTR [rax], OFFSET FLAT:.LC0 mov QWORD PTR [rbp-8], rax mov rax, QWORD PTR [rbp-8] test rax, rax je .L3 mov esi, 8 mov rdi, rax call operator delete(void*, unsigned long)