为什么删除指向指针向量的指针会导致指针无效?
编辑:谢谢你的回答!我宣布tellSomething
方法的std::string
返回类型,而它应该是void
!为什么删除指向指针向量的指针会导致指针无效?
我正在绊倒自己,并指责可怜的无辜delete
运营商:)!
让我们考虑一个指向一个动态分配的vector
其中包含指向动态分配的对象:
// Create the vector of pointers
std::vector<A *>* v = new std::vector<A *>;
// Create two objects
A *a1 = new A;
A *a2 = new A;
// Populate the vector
v->push_back(a1);
v->push_back(a2);
// Delete the vector
delete v;
// Try accessing one of the objects
a1->tellSomething(); --> // Segmentation fault
正如预期的那样,如果我删除vector
,对包含的对象的delete
不叫(我也证实A::~A()
从未在上面的代码中被调用),但是,最后的指令给出了分段错误。
我从delete v
期望是两件事情:
- ,每包含的对象调用析构函数
- 的容器被释放
但是,在这种情况下,所包含的对象是指针,所以没有调用析构函数。
此外,a1
不是NULL
在列表结束。
那么,为什么分段错误?
完整示例:http://ideone.com/r8YC0。
注:我不经常使用与STL容器裸指针,请考虑下面的代码作为一个纯粹的理论例子来帮助我理解delete v
指令的逻辑。
你得到的崩溃是完全不相关的;你宣称tellSomething
返回std::string
,但你永远不会返回任何东西,所以你进入未定义的行为 - 土地;该程序在释放该向量之后崩溃的事实纯属运气,即使在第一次调用tellSomething
时也可能会崩溃。
Fixing that problem使您的程序运行良好(尽管您正在泄漏a1
和a2
)。
顺便说一句,这教你打开了所有的警告:与-Wall
代码就会给你这个潜在问题的一个明确的警告:
[email protected] ~/cpp $ g++ -Wall testwarns.cpp
testwarns.cpp: In member function ‘std::string A::tellSomething()’:
testwarns.cpp:12:5: warning: no return statement in function returning non-void [-Wreturn-type]
(仅仅是为了记录:我个人推荐用-Wall -Wextra -ansi -pedantic
进行编译,通常一个警告可以为你节省很多调试时间)。
+1用于打开警告。 – 2012-07-24 19:19:53
我喜欢用clang的警告是'-Weverything -Werror',然后是一长串'-Wno- *'参数来禁用我不在乎的警告,比如'-Wno-C++ 98-compat - WNO-C++ 98-COMPAT-pedantic'。 – bames53 2012-07-24 19:29:42
您的tellSomething
方法缺少返回值。
将该return "";
添加到该方法使您的代码运行得很好,尽管存在内存泄漏。
可能是这个。 – Wug 2012-07-24 19:18:17
崩溃来自一个尝试呼叫无效std::string
析构函数:
std::string tellSomething() {
std::cout << "A!" << std::endl;
}
至a1->tellSomething();
的调用告诉运行时预计的范围,它然后试图破坏自动存储std::string
。但这是无效的。
从技术上讲,这是未定义的行为,因为你没有返回你答应你会的东西。
自从我是C++:ing以来,它已经有一段时间了,但是如何编译这些代码?我希望它在编译时失败.. – 2012-07-24 19:21:48
@AvadaKedavra MSVS它确实失败。显然海湾合作委员会更宽松...... – 2012-07-24 19:23:41
好吧,纯粹。自从我进入海湾合作委员会以来,它的时间更长了。 +1顺便说一句,很好的答案。 – 2012-07-24 19:24:38
它崩溃,因为在法联代码A::tellSomething
你应该返回std::string
你不这样做。它与删除无关v
它是什么'a1-> tellSomething'在做什么? – Wug 2012-07-24 19:15:26
我相信'delete'关键字调用矢量的析构函数,它会依次删除所有指针 – 2012-07-24 19:15:32
这不应该发生。你怎么知道它不在tellSomething()方法中 - 你排除了这种可能性吗? – mathematician1975 2012-07-24 19:16:26