C++报pointer being freed was not allocated错误,如何定位非法内存访问点
问题根因
1. 直接触发内存错误的根因:拷贝构造函数非法释放野指针
你的Stack拷贝构造函数是用于创建新对象的场景,新对象的_data成员还未初始化,是随机野地址,你在拷贝构造开头执行了if (_data) delete[] _data;,对野指针执行释放操作,直接触发pointer being freed was not allocated报错。拷贝构造是新建对象,不存在提前分配过内存的情况,不需要提前释放。
2. 其他逻辑错误
- Ranking函数泛型兼容性问题:当前你调用了
compare方法,仅字符串类型支持该方法,int类型没有该方法,无法满足同时支持两类数据的需求,直接用>运算符即可,C++已经重载了string的>为字典序比较,完全符合需求。 - 栈残留问题:main函数每次处理完一行输入后,没有清空
strs栈,下一行输入会累加上一行的残留内容,导致统计结果错误。 - 拷贝构造冗余复制:拷贝构造中循环复制了整个
_size长度的数组,实际上栈仅_top个元素是有效内容,不需要复制未使用的空间。 - 空栈越界风险:如果传入Ranking的栈为空,直接取
Elem(0)会出现数组越界访问。
修复后完整代码
#include <iostream> #include <sstream> #include <string> #include <vector> #include <algorithm> const size_t SIZE = 100; using namespace std; template <class T> class Stack { public: Stack(size_t size = SIZE); Stack(const Stack<T>& s); const Stack<T>& operator = (const Stack<T>& s); ~Stack(); bool isfull(); bool isEmpty(); void push(T d); T pop(); T Elem(size_t i); void clear(); private: T *_data; size_t _top, _size; }; template <class T> void Stack<T>::clear() { _top = 0; } template <class T> Stack<T>::Stack(size_t size) : _top(0), _size(size) { _data = new T[size]; } template <class T> Stack<T>::Stack(const Stack<T>& s) : _top(s._top), _size(s._size) { // 删掉了错误的野指针释放逻辑 _data = new T[_size]; // 仅复制有效元素 for (int i = 0; i < _top; ++i) _data[i] = s._data[i]; } template <class T> const Stack<T>& Stack<T>::operator=(const Stack<T>& s) { if (this == &s) return *this; delete[] _data; _size = s._size; _top = s._top; _data = new T[_size]; for (int i = 0; i < _top; ++i) _data[i] = s._data[i]; return *this; } template <class T> Stack<T>::~Stack() { delete [] _data; } template <class T> bool Stack<T>::isfull() { return _top == _size; } template <class T> bool Stack<T>::isEmpty() { return _top == 0; } template <class T> void Stack<T>::push(T d) { if (!isfull()) _data[_top++] = d; } template <class T> T Stack<T>::pop() { if (!isEmpty()) return _data[--_top]; throw -1; } template <class T> T Stack<T>::Elem(size_t i) { return _data[i]; } // 修正泛型兼容性,增加空栈判断 template <class T> int Ranking(Stack<T> obj) { int k = 0; if (obj.isEmpty()) return 0; T base = obj.Elem(0); while(!obj.isEmpty()) { if(obj.pop() > base) k++; } return k; } int main(void) { string s; string line; Stack<string> strs; vector<int> nums; while (getline(cin, line)) { strs.clear(); // 每次处理新行前清空栈 istringstream ins(line); while (ins >> s) { strs.push(s); } int res = Ranking(strs); cout << res << endl; // 输出结果 nums.push_back(res); } return 0; }
验证结果
- 输入
4 1 +2 5 3 -1 6,输出2,符合示例1要求 - 输入
to be or not to be,输出0,符合示例2要求
内容的提问来源于stack exchange,提问作者차현대
相关产品推荐
相关产品推荐

