提问人:BrownBear2018 提问时间:10/13/2021 最后编辑:BrownBear2018 更新时间:10/13/2021 访问量:53
编译器错误“未分配的指针未分配”仅在 C++ 中使用自定义对象的 foreach 循环时
Compiler error "Pointer being freed was not allocated" only while using a foreach loop of custom objects in C++
问:
我有一个作业,我构建了自己的字符串类。我制作了几个 MYString 对象并将它们放在一个向量中。当我通过下标运算符访问向量时,我没有问题。但是当我使用 foreach 循环遍历向量时,我得到一个奇怪的错误“”未分配被释放的指针”
- 我搞砸了我的复制构造函数吗?
- 我的析构函数和 clear() 函数搞砸了吗?
头文件如下:
class MYString{
friend std::ostream& operator<<(std::ostream&, const MYString&);
friend std::istream& operator>>(std::istream&, MYString&);
private:
static const int INITIAL_CAP = 20;
char* str;
static int getLength(const char*);
int cap; //capacity of the char array, in multiples of 20
int end; // location of the null terminator
int compareTo(const MYString& rhs);
void clear(); // to manually free memory
static int requiredCap(int end);
public:
MYString();
MYString(const MYString& mystr);
MYString(const char*);
~MYString();
MYString& operator=(const MYString& rhs);
char& operator[](int index);
const char& operator[](int index) const;
int length() const;
int capacity() const;
const char* c_str();
MYString operator+(const MYString& rhs);
int operator==(const MYString& rhs);
int operator>(const MYString& rhs);
int operator<(const MYString& rhs);
};
Here is some relevant function defintions
MYString::MYString(const MYString& rhs){
*this = rhs;
}
MYString& MYString::operator=(const MYString& rhs){
if (this == &rhs){
return *this;
}
clear();
cap = rhs.cap;
end = rhs.end;
str = new char[cap];
for (int i = 0; i < end; i++){
str[i] = rhs[i];
}
str[end] = '\0';
return *this;
}
MYString::~MYString(){
clear();
}
void MYString::clear(){
cap = 0;
end = 0;
delete[] str;
str = nullptr;
}
The main method is as follows:
#include "MYString.h"
#include <iostream>
#include <vector>
#include <fstream>
using namespace std;
int main(){
ifstream input;
input.open("file.txt");
if (input.fail()){
cout << "File error" << endl;
}
MYString s;
vector<MYString> v;
int count = 0;
v.push_back(MYString());
int index = 0;
while (input >> s){
if (count == 2){
v.push_back(MYString());
count = 0;
index++;
}
if (count < 2){
v[index] = v[index] + s;
count++;
}
}
for (MYString& str : v){
cout << str << endl;
}
答:
0赞
Chris Uzdavinis
10/13/2021
#1
构造函数存在严重问题:
MYString::MYString(const MYString& rhs){
*this = rhs;
}
在对象的主体中,您的数据不会初始化,但您可以取消引用并分配给它。数据成员包含垃圾,包括指针。在赋值运算符中,调用 clear,这将调用此垃圾指针。这是未定义的行为。delete[]
在赋值方面实现构造函数总是错误的。赋值用于将初始化对象的状态替换为新状态,而构造函数则为未初始化的成员提供初始状态。在构造函数完成之前,对象的生存期甚至还没有开始。在生命尚未正式开始的对象上调用函数是未定义的行为。
复制构造函数需要分配内存并将数据复制到内存中,这与在赋值运算符中执行的操作类似,但不会先清理旧状态。此外,请考虑使用 strcpy 而不是循环来复制字节。它会更快。
评论
cout << v[4] << endl;
clear()
delete[]
str
nullptr
)