删除运算符的确切操作
the exact operation of the delete operator
我听说过很多关于 C++ delete
operator 并且到目前为止我也经常使用它,但我不知道它的真正作用到底是什么。
我在网上看到的是 "Deallocating storage space" 上关于它的讨论,但对我来说完全理解这个问题并没有什么意义。
请查看下面的代码片段。
int main()
{
int* p = new int(6);
cout << *p << endl;
delete p;
}
指针 p
有自己的地址,因为它是一个变量 (#1)。指针 p
本身也有一个地址,因为它是一个指针(#2)。该对象(未命名)在其内存块中包含值 6,并且该内存块的地址与 #2
的地址相同。 (因为指针使用该地址指向该对象。)
现在,执行delete;
后地址#1和#2会发生什么?
C++ 语言对此有何看法?
各种编译器对这种情况的影响是什么?
关于
” The exact operation of the delete operator
问题中的示例代码:
delete p;
那是一个delete
表达式,不是直接调用delete
运算符。运算符是一个释放函数,通常由 delete
表达式调用,在 delete
表达式调用对象析构函数(或对于数组,这样的序列)之后。事情是这样的:
如果 p
指向一个 class 类型的对象,那么调用它的析构函数来清理东西,例如释放资源。
调用相关的释放函数 operator delete
来释放内存。这通常是全局 operator delete
,但它可以是由相关 class 定义的 operator delete
。
值得注意的是,对于放置 new
表达式,如果在 new
表达式求值期间构造失败,则使用相同的分配器参数调用放置释放函数,但稍后 delete
表达式只调用普通的标准参数 operator delete
。我不知道这样做的理由。但这导致了一些错误,尤其是 MFC 中一个臭名昭著的错误,它仅出现在调试版本中,内存泄漏。
int main() {
int* p; // p is at address #1 and the value uninitialized. p will
// be at address #1 throughout the whole program.
// It is only the value of p that can change.
p = new int(6); // The value of p is set to address #2 and your
// program now has ownership of sizeof(int) bytes
// starting from address #2. The int at address #2
// is initialized with the value 6.
cout << *p << endl;
delete p; // Your program releases ownership of the memory at
// address #2 and you are not allowed to use it anymore.
// The value of p is undefined.
return 0;
}
在 delete p
之后,p
仍然具有与以前相同的地址。对象不见了,所以它没有地址。它曾经占用的字节可能被用于其他用途,或者可能已返回给 OS;如果不调用未定义的行为,您将无法查看它们。
p
的值不再有用 - 您不能对 p
做太多事情,只能为其分配一个新值或让它被销毁。
这就是语言所说的,编译器会实现它。
Now, what will happen over the address #1, #2 after executing delete; (in the code) please?
指针 p
将有一个未定义的值,但它会保留其地址(“#1”)。
位于 *p
的 int
对象(地址为“#2”)不再存在。该地址现在描述了可在未来分配中免费使用的内存。
What does the C++ language say about this?
这个:
[C++14: 5.3.5/1]
: The delete-expression operator destroys a most derived object (1.8) or array created by a new-expression. [..]
[C++14: 5.3.5/7]:
If the value of the operand of the delete-expression is not a null pointer value, then:
- If the allocation call for the new-expression for the object to be deleted was not omitted (5.3.4), the delete-expression shall call a deallocation function (3.7.4.2). The value returned from the allocation call of the new-expression shall be passed as the first argument to the deallocation function.
- Otherwise, the delete-expression will not call a deallocation function (3.7.4.2).
And what can be the effect of various compilers on the case?
只要他们合规,none。所有编译器的行为方式必须相同。
我听说过很多关于 C++ delete
operator 并且到目前为止我也经常使用它,但我不知道它的真正作用到底是什么。
我在网上看到的是 "Deallocating storage space" 上关于它的讨论,但对我来说完全理解这个问题并没有什么意义。
请查看下面的代码片段。
int main()
{
int* p = new int(6);
cout << *p << endl;
delete p;
}
指针 p
有自己的地址,因为它是一个变量 (#1)。指针 p
本身也有一个地址,因为它是一个指针(#2)。该对象(未命名)在其内存块中包含值 6,并且该内存块的地址与 #2
的地址相同。 (因为指针使用该地址指向该对象。)
现在,执行delete;
后地址#1和#2会发生什么?
C++ 语言对此有何看法?
各种编译器对这种情况的影响是什么?
关于
” The exact operation of the delete operator
问题中的示例代码:
delete p;
那是一个delete
表达式,不是直接调用delete
运算符。运算符是一个释放函数,通常由 delete
表达式调用,在 delete
表达式调用对象析构函数(或对于数组,这样的序列)之后。事情是这样的:
如果
p
指向一个 class 类型的对象,那么调用它的析构函数来清理东西,例如释放资源。调用相关的释放函数
operator delete
来释放内存。这通常是全局operator delete
,但它可以是由相关 class 定义的operator delete
。
值得注意的是,对于放置 new
表达式,如果在 new
表达式求值期间构造失败,则使用相同的分配器参数调用放置释放函数,但稍后 delete
表达式只调用普通的标准参数 operator delete
。我不知道这样做的理由。但这导致了一些错误,尤其是 MFC 中一个臭名昭著的错误,它仅出现在调试版本中,内存泄漏。
int main() {
int* p; // p is at address #1 and the value uninitialized. p will
// be at address #1 throughout the whole program.
// It is only the value of p that can change.
p = new int(6); // The value of p is set to address #2 and your
// program now has ownership of sizeof(int) bytes
// starting from address #2. The int at address #2
// is initialized with the value 6.
cout << *p << endl;
delete p; // Your program releases ownership of the memory at
// address #2 and you are not allowed to use it anymore.
// The value of p is undefined.
return 0;
}
在 delete p
之后,p
仍然具有与以前相同的地址。对象不见了,所以它没有地址。它曾经占用的字节可能被用于其他用途,或者可能已返回给 OS;如果不调用未定义的行为,您将无法查看它们。
p
的值不再有用 - 您不能对 p
做太多事情,只能为其分配一个新值或让它被销毁。
这就是语言所说的,编译器会实现它。
Now, what will happen over the address #1, #2 after executing delete; (in the code) please?
指针 p
将有一个未定义的值,但它会保留其地址(“#1”)。
位于 *p
的 int
对象(地址为“#2”)不再存在。该地址现在描述了可在未来分配中免费使用的内存。
What does the C++ language say about this?
这个:
[C++14: 5.3.5/1]
: The delete-expression operator destroys a most derived object (1.8) or array created by a new-expression. [..]
[C++14: 5.3.5/7]:
If the value of the operand of the delete-expression is not a null pointer value, then:
- If the allocation call for the new-expression for the object to be deleted was not omitted (5.3.4), the delete-expression shall call a deallocation function (3.7.4.2). The value returned from the allocation call of the new-expression shall be passed as the first argument to the deallocation function.
- Otherwise, the delete-expression will not call a deallocation function (3.7.4.2).
And what can be the effect of various compilers on the case?
只要他们合规,none。所有编译器的行为方式必须相同。