为何注释s.pop()后C++栈类的Destructor未被调用?
栈实现中析构函数未执行的技术原因分析
问题代码
#include<iostream> using namespace std; class stack { public: int *top; int size, capacity; stack(int c):capacity(c){ size = 0; top = new int[capacity]; capacity = capacity - 1; } ~stack() // deleting the stack at the end of program { delete[] top; top = NULL; cout << "deleted the stack" << endl; } void push(int data) { // Is there is a space if(is_stackFull()) { cout << "stack is full" << endl; return; } // populate the data *top = data; // updating the stack variables top += 1; size += 1; return; } void pop() { // is stack empty if(is_stackEmpty()) { cout << "stack is empty" << endl; return; } // update the stack variables top -= 1; size -= 1; return; } bool is_stackFull() { return (size == capacity); } bool is_stackEmpty() { return (size == 0); } }; int main() { stack s(10); s.push(15); //s.pop(); // what happens to the output when i comment out this code? return 0; }
问题描述
当注释掉main函数中的s.pop()调用后,栈的析构函数似乎未被执行(没有输出deleted the stack),请解释该现象的技术原因。
原因分析
核心问题在于违反了delete[]的使用规则,触发了C++的未定义行为,具体过程如下:
- 构造函数的指针初始化:构造函数中
top = new int[capacity];分配了数组内存,此时top指向数组的首地址(即new[]返回的原始指针)。 - push操作的指针偏移:调用
push(15)时,先给当前top指向的位置赋值,再执行top += 1;,导致top指针偏移到数组的下一个元素位置,不再指向最初分配的首地址。 - 析构函数的非法操作:程序结束销毁对象
s时,析构函数执行delete[] top;,但C++规定delete[]必须传入**new[]返回的原始指针**。传入偏移后的指针属于未定义行为,程序可能直接崩溃或终止,导致析构函数中后续的cout语句无法执行,看起来就像析构函数没被调用。 - 调用pop时的正常逻辑:如果执行
s.pop(),top -= 1;会把指针回调到数组首地址,此时delete[] top是合法操作,析构函数能正常执行并输出提示信息。
注意:未定义行为的表现具有不确定性,不同编译器、运行环境下可能有不同结果,但本质原因都是指针偏移导致
delete[]使用了错误的指针。
内容的提问来源于stack exchange,提问作者siva ramaraju siv
相关产品推荐
相关产品推荐

