我正面临一个问题。我写了以下程序:
void main() {
int *ptr;
ptr=new int;
cout<<ptr<<endl;
cout<<&ptr<<endl;
delete ptr;
// ptr = NULL;
cout<<ptr<<endl;
cout<<&ptr<<endl;
} 该计划的输出是:
0x00431810 0x0018FF44 0x00431810 0x0018FF44
“&amp; ptr”肯定是一样的,因为它是ptr自己的地址。但是输出的第1行和第3行清楚地表明,即使在调用“删除”之后,“ptr”也指向相同的存储位置。为什么?如果是这种情况,为什么我们有“删除”而不仅仅依赖NULLING指针。我知道不止一个指针可以指向一个内存位置,但是“删除”是没用的。不是吗?这太令人困惑了。请帮忙。我明天考试。
答案 0 :(得分:3)
delete ptr
不会改变指针的值,但会释放内存。
请注意,释放内存后取消引用ptr
会触发undefined behaviour。
答案 1 :(得分:1)
当您调用new时,您要求计算机在堆上分配一些内存并返回指向堆上的位置的指针。
调用delete的做法恰恰相反,它告诉计算机释放指针从堆中指向的内存。这意味着它可以在以后的阶段由您的程序重用。
但是,它不会更改指针的值。最好将指针值设置为NULL
。这是因为,指针现在指向的位置可能包含任何内容(计算机可以自由地重复使用此内存)。如果你使用这个指针,它将是未定义会发生什么。
如果您只是将指针更改为NULL
,那么所有这一切都会忘记您分配内存的位置。因为C ++不是托管语言,所以它不会检测到你没有任何指向该内存的指针,因此内存将因为你无法访问它而丢失(你不知道它在哪里)而是计算机不能重复使用它(它不知道你已经完成它)。
如果使用C#或Java之类的托管语言,当堆上没有指针时,计算机会释放它(称为垃圾收集),但这会带来性能开销,因此C ++会将其留给程序员。
答案 2 :(得分:1)
指针不知道内存是有效还是已损坏。您可以指向指向任何可以寻址的地址(适合指针)。例如,我的机器指针有8个字节大小,所以我可以做
int main(int argc, char** argv) {
int *ptr;
ptr=new int;
cout<<ptr<<endl;
cout<<&ptr<<endl;
delete ptr;
//ptr= NULL;
cout<<ptr<<endl;
cout<<&ptr<<endl;
ptr = (int*) 0xffffffff;
cout<<ptr<<endl; //prints 0xffffffff
ptr = (int*) 0xffffffffffffffff;
cout<<ptr<<endl; //prints 0xffffffffffffffff
ptr = (int*) 0xffffffffffffffff1;
cout<<ptr<<endl; //prints 0xfffffffffffffff1 truncated
ptr = (int*) 0xffffffffffffffff321;
cout<<ptr<<endl; //prints 0xfffffffffffff321 truncated
return 0;
}
当你使用new时,它将在堆上的某个地址分配内存并返回指向该地址的指针。
void* operator new (std::size_t size) throw (std::bad_alloc);
指针和内存是两个不同的东西。特别是,您甚至可以手动指定要用于分配的地址(使用放置新语法):
int* ptr = new (0xff1256) int;
//correct if the memory at 0xff1256 is preallocated
//because placement new only creates object at address
//doesn't allocate memory
“ptr”即使在“删除”之后也指向相同的内存位置 叫做。为什么呢?
以同样的方式delete ptr
只释放内存,保持指针不变(尽管在调用delete
之后立即为指针指定NULL)这是一个很好的做法。它只释放内存,它对你的指针不感兴趣但在地址中释放内存。分配内存或取消分配内存是由操作系统完成的(即内存被标记为已分配)。
答案 3 :(得分:0)
释放由ptr指向的内存块(如果不为null) 先前通过调用operator new分配给它的存储空间 并且呈现指针位置无效。
这意味着,delete
标记任何其他进程为任何其他目的重用的位置。它从未说过,它会将内存块初始化为任意随机值,以便永远不会再次访问先前存储的数据。因此,即使在调用delete
之后,也始终可以提供数据。但是,再一次,这只是Undefined Behavior
的可能性之一。多数民众赞成为什么编码,在解除分配后指针NULL
。