delete[]和delete的行为似乎相似
delete[] and delete seems to behave alike
这里,如果我使用delete
或delete[]
,输出仍然是70。我能知道为什么吗?
#include<iostream>
using namespace std;
int main()
{
int* c = new int[100];
for(int i=0; i<98; i++)
{
c[i] = i;
}
cout<<c[70]<<endl;
delete[] c;
or
delete c;
cout<<c[70]<<endl; //outputs 70 even after delete[] or delete
return 0;
}
访问已删除的内存是未定义的行为。用错误的delete
删除也是UB。任何进一步的讨论都是毫无意义的,因为你无法可靠地期待任何结果。
在许多情况下,UB只会做"正确"的事情,但你需要意识到,这完全是"偶然"的,可能会随着另一个编译器、同一编译器的另一个版本、天气。。。为了获得正确的代码,您需要避免UB的所有情况,即使是那些看起来有效的情况。
使用new
只会为程序分配一些内存,并返回一个指向所述内存地址的指针,为数据类型保留所需的内存。当您稍后使用delete
时,它会"释放"内存,但不会删除其内容。如果您有一个值为70的int
存储在该地址,那么它仍将包含70,直到另一个应用程序需要一些内存,获得所述地址并在其中放入另一个值。
如果您使用new
为数组分配内存,您将保留以下内存块,直到有足够的块用于指定的数组长度。
假设您执行以下操作:
int main() {
int* array = new int[10]; // array now points to the first block of the allocated memory
delete array; // since array points to the first block of the array, it will only free that block, but nothing else, causing a memory leak
delete[] array; // will free all memory allocated by the previous new
// Note that you should never free allocated memory twice, like in this code sample. Using delete on already freed memory is undefined behaviour!
]
始终对单个变量使用delete
,对数组使用delete[]
。
演示您的问题:
int main() {
int* c = new int[10]; // We allocate memory for an array of 10 ints
c[0] = 1; // We set the value of the first int inside the array to 1
delete[] c;
/*
* We free the previously allocated memory.
* Note that this does not delete the CONTENT of the memory!
* c does still point towards the first block of the array!
*/
std::cout << c[0];
/*
* Firstly, this is undefined behaviour (Accessing deallocated memory).
* However, this will output 1,
* unless some other process allocated the memory at the address
* and filled it with another value already. (Very unlikely)
*/
return 0;
}
如果要删除/覆盖已删除内存的内容,可以使用std::memset
。
示例:
#include <cstring>
int main() {
std::size_t length = 10;
int* c = new int[length];
c[0] = 1;
std::cout << c[0] << std::endl; // Will output 1
std::memset( c, 0, length ); // Fill the memory with 0 bytes
delete[] c; // Now we free the array's memory
std::cout << c[0] << std::endl; // Will output 0
}
正如其他人所指出的,它的未定义行为和任何事情都可能发生。借助像valgrind这样的工具可以很容易地捕捉到这些。
相关文章:
- 模板元程序查找相似的连续类型名称
- 运算符C++ "delete []"仅删除 2 个前值
- g++用户定义的动态链接库上的全局new和delete运算符
- 为什么"delete"关键字不删除节点?
- 为什么这些完全相似的代码不起作用?
- "delete"在 C++ 中实际上做了什么?
- 析构函数和'delete'之间的区别
- 这两个代码片段相似,但显示的结果不同
- 父类的私有函数会导致对具有相同名称和相似参数的子类中的公共函数的不明确调用
- 如何知道何时调用删除以及何时调用 delete[] C++?
- 在对象指针上调用 Delete 是否会递归删除其动态分配的成员
- 体系结构x86_64的未定义符号:std:terminate(),typeinfo,运算符delete[],运算符new
- 如何编写具有相同名称的相同函数,该函数在C++中几乎以相似的方式处理不同的类参数?
- 析构函数中的"delete this"
- 为什么数组大小信息可用于"sizeof"运算符和 delete[] 运算符,但在将数组作为参数传递到
- 即使在使用 delete[] 后仍保留的元素
- 如果我在下面的代码片段中添加"delete[] d;",为什么我得到零?
- 程序来检查两个数组的相似元素
- C++设置名称相似的变量的值
- delete[]和delete的行为似乎相似