英文:
Not sure where to put my delete function without getting a segmentation fault?
问题
以下是代码部分的翻译:
我有一个名为 MyObject 的对象,其中包含成员变量,用于保存名称(这是重载构造函数设置的内容)和一个字符数据的链接列表。我从一个文件中读取了一堆以以下格式存储的 MyObjects:
name,a,b,c,d
name1,a,b,c,d,e
// 等等
我的代码应该获取每个对象并将其添加到 myVect 中:
vector<MyObject*> myVect;
我的问题是,我使用 new
来分配内存。当然,我知道这意味着我需要使用 delete
(而当我没有使用 delete
时,会导致内存泄漏,因此我不认为这是双重删除问题),但无论我在何处删除 ptr
,都会导致分段错误。
我希望 myVect 不仅仅保存指针,但由于需要进行赋值,所以必须这样做。
以下是代码:
void Sequencer::ReadFile() {
ifstream fin;
fin.open(fileName);
cout << "打开文件" << endl;
string line = "";
MyObject* ptr;
while(getline(fin, line)) {
string name = "";
int count = 0;
while(line[count] != ',') {
name += line[count];
count++;
}
ptr = new MyObject(name);
for(int i = count + 1; i < line.size(); i+=2) {
(*ptr).InsertEnd(line[i]);
}
myVect.push_back(ptr);
//delete ptr;
//ptr = nullptr;
}
//delete ptr;
//ptr = nullptr;
fin.close();
}
请注意,这是您提供的代码的翻译部分,不包括其他内容。
英文:
I have an object MyObject with member variables that hold a name (which is what the overloaded constructor sets and a linked list of character data. I read in from a file that has a bunch of MyObjects in the following format:
name,a,b,c,d
name1,a,b,c,d,e
// etc.
My code is supposed to grab each object and add it to myVect
vector<MyObject*> myVect;
My problem is that I use new to allocate. Of course I know this means I need delete (and when I don't have delete there are memory leaks so I don't think this a double deletion issue), but no matter where I delete ptr, it cause a segmentation fault.
I would love for myVect to not hold pointers but it has to (assignment).
Here's the code
void Sequencer::ReadFile() {
ifstream fin;
fin.open(fileName);
cout << "Opened File" << endl;
string line = "";
MyObject* ptr;
while(getline(fin, line)) {
string name = "";
int count = 0;
while(line[count] != ',') {
name += line[count];
count++;
}
ptr = new MyObject(name);
for(int i = count + 1; i < line.size(); i+=2) {
(*ptr).InsertEnd(line[i]);
}
myVect.push_back(ptr);
//delete ptr;
//ptr = nullptr;
}
//delete ptr;
//ptr = nullptr;
fin.close();
}
答案1
得分: 1
记住,你不应该delete
指针,而应该delete
指针指向的对象。这意味着在ReadFile
中的任何地方都不应该delete ptr
,因为你希望指向的对象在myVect
持有指针的整个生存期内都继续存在。
相反,你应该在myVect
中的指针指向的每个对象完成后进行delete
操作。最常见的地方是在myVect
所属的对象的析构函数中。例如:
Sequencer::~Sequencer() {
for (MyObject* p : myVect) {
delete p;
}
}
当然,如果你使用智能指针而不是裸指针,那么你就不需要手动delete
任何东西。例如,myVect
可以是std::vector<std::unique_ptr<MyObject>>
。在这种情况下,unique_ptr
在其生命周期结束时会自动delete
它们指向的对象。
在这种情况下,你需要将ReadFile
更改为以下内容:
void Sequencer::ReadFile() {
std::ifstream fin(fileName);
std::string line = "";
while(std::getline(fin, line)) {
std::string name = "";
int count = 0;
while(line[count] != ',') {
name += line[count];
count++;
}
std::unique_ptr<MyObject> ptr = std::make_unique<MyObject>(name);
for(int i = count + 1; i < line.size(); i+=2) {
ptr->InsertEnd(line[i]);
}
myVect.push_back(ptr);
}
}
前提是你是否真的需要使用指针。你当前的ReadFile
实现没有特殊原因来动态分配对象。如果可能的话,最好的解决方案是让myVect
成为std::vector<MyObject>
,并让std::vector
自己处理所有对象的生命周期:
void Sequencer::ReadFile() {
std::ifstream fin(fileName);
std::string line = "";
while(std::getline(fin, line)) {
std::string name = "";
int count = 0;
while(line[count] != ',') {
name += line[count];
count++;
}
MyObject obj(name);
for(int i = count + 1; i < line.size(); i+=2) {
obj.InsertEnd(line[i]);
}
myVect.push_back(obj);
}
}
英文:
Remember, you do not delete
pointers, you delete
the thing a pointer points to. That means that it doesn't make sense to delete ptr
anywhere in ReadFile
, since you want the pointed-to objects to continue to exist for as long as myVect
holds pointers to them.
Instead you want to delete
each object pointed to by the pointers in myVect
whenever you're finished with them. The most common place for that is in the destructor of the object that myVect
is a member of. For example:
Sequencer::~Sequencer() {
for (MyObject* p : myVect) {
delete p;
}
}
Of course, if you just used smart pointers instead of raw pointers then you wouldn't need to manually delete
anything. For instance, myVect
could be a std::vector<std::unique_ptr<MyOjbect>>
. In that case the unique_ptr
s would automatically delete
the object they point to when their lifetime ends.
In that case you would change ReadFile
to something like this:
void Sequencer::ReadFile() {
std::ifstream fin(fileName);
std::string line = "";
while(std::getline(fin, line)) {
std::string name = "";
int count = 0;
while(line[count] != ',') {
name += line[count];
count++;
}
std::unique_ptr<MyObject> ptr = std::make_unique<MyObject>(name);
for(int i = count + 1; i < line.size(); i+=2) {
ptr->InsertEnd(line[i]);
}
myVect.push_back(ptr);
}
}
That's all assuming you need pointers at all. Your current ReadFile
implementation doesn't have any particular reason to dynamically allocate objects. If possible, the best solution would be to just have myVect
be a std::vector<MyObject>
and let std::vector
handle all of the objects' lifetimes itself:
void Sequencer::ReadFile() {
std::ifstream fin(fileName);
std::string line = "";
while(std::getline(fin, line)) {
std::string name = "";
int count = 0;
while(line[count] != ',') {
name += line[count];
count++;
}
MyObject obj(name);
for(int i = count + 1; i < line.size(); i+=2) {
obj.InsertEnd(line[i]);
}
myVect.push_back(obj);
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论