我的第一个C ++分配的要求之一是我们必须确保已释放任何已分配的空间。但是,当我试图确定是否以及如何解除分配非指针变量时,我遇到了一个问题。我已经看到在范围之外这些变量被解除分配,但也可以有:
int var_name=new int(6);
...
delete &var_name;
似乎都在运行,但我不明白为什么或如何解除分配地址可能会导致问题。
感谢。
答案 0 :(得分:0)
您只需要释放已使用new
初始化的变量。
答案 1 :(得分:0)
您可以记住以下几点:
只有在使用new运算符显式分配内存时才需要取消分配内存。如果未使用new运算符,则在堆栈上分配内存,并在超出范围时取消分配。另一方面,使用new运算符,内存在堆上分配,必须明确删除。考虑一下:
虚空乐趣() {
// 1. memory allocation on stack
int var_on_stack = 10;
// 2. memory allocation on heap
int* var_on_heap_ptr = new int ( 10 );
// 3. delete memory allocated on heap
delete var_on_heap_ptr;
}
在语句1中,为var_on_stack分配4个字节(考虑整数占用4个字节)。此内存在堆栈中,无需显式删除。 在语句2中,再次在堆上分配4个字节,并将第一个位置的地址分配给var_on_heap_ptr。当使用new在堆上分配内存时,编译器将分配所需的内存量并返回第一个内存位置的地址。这就是var_on_heap_ptr被声明为整数指针的原因。此内存在堆上分配,必须由用户使用delete运算符显式删除。在你的问题中,你已经写了你的第一个声明。它不应该。您必须将var_name声明为int *而不是int才能使其工作,否则您将收到编译错误。
取消分配堆上分配的内存时,请使用delete运算符。 delete运算符将指针作为参数,并假定指针指向的内存位置是使用new运算符分配的。请记住它会假设并且不会验证。如果将堆栈变量的地址传递给delete,则该内存将被解除分配两次。一旦通过删除操作符,并在变量超出范围时再次执行。正如任何c ++程序员都会告诉你的那样,这是一个灾难性的确定方法。
再次考虑以下声明:
int * var_on_heap_ptr = new int(10);
这里指针变量var_on_heap_ptr将包含在堆上分配的内存地址,但变量本身将驻留在堆栈上。这意味着编译器将首先为指针变量var_on_heap_ptr分配四个字节(通常,指针变量将占用四个字节,但它可以取决于机器)。这个内存在堆栈上。接下来,编译器将为堆上的整数分配四个字节,并将这四个字节的第一个地址存储在var_on_heap_ptr变量中。这意味着变量本身位于堆栈上,但其值是(即指向)堆上分配的内存位置的地址。当你说 delete var_on_heap_ptr; 编译器将解除分配var_on_heap_ptr指向的“内存”,即堆上分配的内存。然后当你超出范围时,分配给var_on_heap_ptr变量的内存将由编译器解除分配,因为变量在堆栈上。因此,在堆和堆栈上分配的所有内存都将被取消分配。
最后一点。请注意,delete运算符将删除var_on_heap_ptr变量指向的内存,但会保持变量的内容不变。这意味着如果var_on_heap_ptr在删除操作之前包含0xaabbccdd作为内存地址,则即使在删除操作完成后它仍将继续保持0xaabbccdd。不同之处在于删除之前指针变量指向堆上分配的内存,但删除后内存已被释放,变量现在指向解除分配的内存(现在可能已分配给其他某些进程),因此不能可靠的。这意味着如果您现在尝试使用指针变量,程序可能会崩溃。此外,如果您尝试删除变量两次,编译器将再次尝试取消分配变量指向的内存,结果可能是灾难性的。为了避免在对指针变量调用delete操作之后,将指针变量设置为NULL是好的,这样即使有人再次对此变量调用delete,程序也不会崩溃,因为对NULL的删除操作是安全的。
希望这会有所帮助。