为什么shared_ptr不删除它的记忆?
Why does shared_ptr not delete its memory?
int main(){
int* iptr;
{
std::shared_ptr<int> sptr = std::make_shared<int>(12);
iptr = sptr.get();
}
std::cout << *iptr;
return 0;
}
输出
12
我原以为 iptr 指向的内容会在内部花括号的末尾被删除。但是输出显示 12。我错过了什么吗?
Why does shared_ptr not delete its memory?
shared_ptr 是否删除它作为最后一个所有者时拥有的内存。
I was expecting that the content to which iptr points, would have been deleted, at the end of inner curly braces.
您的预期是正确的。
But output shows 12. Do I miss something?
您没有注意到通过无效指针进行访问会导致未定义的行为。
正如 eerorika 正确指出的那样,您在这里看到了未定义的行为。特别是 悬挂指针 。 IE。指向具有已删除内存的位置的指针。您不仅可以获得任意结果,而且您的程序可能会以完全出乎意料的方式运行。
我强烈建议使用消毒剂来避免此类问题。这是使用 -fsanitize=address
(https://gcc.godbolt.org/z/Po3r9cvq7) 编译的代码的输出:
=================================================================
==1==ERROR: AddressSanitizer: heap-use-after-free on address 0x603000000020 at pc 0x000000401439 bp 0x7fff630ed360 sp 0x7fff630ed358
READ of size 4 at 0x603000000020 thread T0
#0 0x401438 in main /app/example.cpp:12
#1 0x7fdd09b5b0b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x270b2)
#2 0x40121d in _start (/app/output.s+0x40121d)
如您所见,它指出您正在尝试访问已删除的内存。它还为分配和释放内存的操作提供了调用堆栈,非常方便。
int main(){
int* iptr;
{
std::shared_ptr<int> sptr = std::make_shared<int>(12);
iptr = sptr.get();
}
std::cout << *iptr;
return 0;
}
输出
12
我原以为 iptr 指向的内容会在内部花括号的末尾被删除。但是输出显示 12。我错过了什么吗?
Why does shared_ptr not delete its memory?
shared_ptr 是否删除它作为最后一个所有者时拥有的内存。
I was expecting that the content to which iptr points, would have been deleted, at the end of inner curly braces.
您的预期是正确的。
But output shows 12. Do I miss something?
您没有注意到通过无效指针进行访问会导致未定义的行为。
正如 eerorika 正确指出的那样,您在这里看到了未定义的行为。特别是 悬挂指针 。 IE。指向具有已删除内存的位置的指针。您不仅可以获得任意结果,而且您的程序可能会以完全出乎意料的方式运行。
我强烈建议使用消毒剂来避免此类问题。这是使用 -fsanitize=address
(https://gcc.godbolt.org/z/Po3r9cvq7) 编译的代码的输出:
=================================================================
==1==ERROR: AddressSanitizer: heap-use-after-free on address 0x603000000020 at pc 0x000000401439 bp 0x7fff630ed360 sp 0x7fff630ed358
READ of size 4 at 0x603000000020 thread T0
#0 0x401438 in main /app/example.cpp:12
#1 0x7fdd09b5b0b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x270b2)
#2 0x40121d in _start (/app/output.s+0x40121d)
如您所见,它指出您正在尝试访问已删除的内存。它还为分配和释放内存的操作提供了调用堆栈,非常方便。