gpt4 book ai didi

c++ - 如何阻止内存泄漏?

转载 作者:行者123 更新时间:2023-11-30 00:52:26 25 4
gpt4 key购买 nike

我不断收到编译器的错误消息,说存在内存泄漏,两个 8 字节 block 和一个 5 字节 block 。我已经在析构函数中删除了 *name 数组。析构函数如何处理作用域?我的印象是,一旦 main 结束,fruit 对象将在超出范围时被删除。

#include "Fruit.h"
#include "LeakWatcher.h"

using namespace std;
Fruit::Fruit(const Fruit &temp )
{
name = temp.name;
for(int i = 0; i < CODE_LEN - 1; i++)
{
code[i] = temp.code[i];
}
}
void Fruit::operator=(const Fruit &tempFruit)
{
name = tempFruit.name;
for(int i = 0; i < CODE_LEN; i++)
{
code[i] = tempFruit.code[i];
}

}
Fruit::~Fruit()
{
delete[] name;

}
bool Fruit::operator==(const Fruit &tempFruit)
{
int i = 0;
while(name[i] != NULL && tempFruit.name[i] != NULL)
{
if(name[i] != tempFruit.name[i])
return false;
i++;
}
if(name[i] != NULL || tempFruit.name[i] != NULL)
return false;
return true;
}
bool Fruit::operator<(const Fruit &tempFruit)
{
int i = 0;
while(name[i] != NULL && tempFruit.name[i] != NULL)
{
if((int)name[i] < (int)tempFruit.name[i])
return true;
else if((int)name[i] > (int)tempFruit.name[i])
return false;
i++;
}
if(name[i] == NULL && tempFruit.name[i] != NULL)
return true;
else
return false;
}
std::ostream & operator<<(std::ostream &os, const Fruit *printFruit)
{
os << setiosflags(ios::left) << setw(MAX_NAME_LEN) << printFruit->name << " ";
for(int i = 0; i < CODE_LEN; i++)
{
os << printFruit->code[i];
}
os << endl;
return os;
}

std::istream & operator>>(std::istream &is, Fruit *readFruit)
{

string tempString;
is >> tempString;
int size = tempString.length();
readFruit->name = new char[tempString.length()];
for(int i = 0; i <= (int)tempString.length(); i++)
{
readFruit->name[i] = tempString[i];
}
readFruit->name[(int)tempString.length()] = '\0';
for(int i =0; i < CODE_LEN; i++)
{
is >> readFruit->code[i];
}
return is;
}
void stuff()
{

}
void main()
{
_CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE );
_CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDOUT );
_CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE );
_CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDOUT );
_CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_FILE );
_CrtSetReportFile( _CRT_ASSERT, _CRTDBG_FILE_STDOUT );
Fruit *fruit = new Fruit();
Fruit *fruit1 = new Fruit();
cin >> fruit;
*fruit1 = *fruit;
cout << fruit << fruit1;
_CrtDumpMemoryLeaks();

}

H

#ifndef _FRUIT_H
#define _FRUIT_H
#include <cstring>
#include <sstream>
#include <iomanip>
#include <iostream>
enum { CODE_LEN = 4 };
enum { MAX_NAME_LEN = 30 };
class Fruit
{
private:
char *name;
char code[CODE_LEN];
public:
Fruit(const Fruit &temp);
Fruit(){name = NULL;};
bool operator<(const Fruit &other);
friend std::ostream & operator<<(std::ostream &os, const Fruit *printFruit);
bool operator==(const Fruit &other);
bool operator!=(const Fruit &other){return!(*this==other);};
friend std::istream & operator>>(std::istream& is, Fruit *readFruit);
void Fruit::operator=(const Fruit &tempFruit);
~Fruit();
};
#endif

最佳答案

“泄漏”的主要来源似乎是“fruit”和“fruit1”指针 - _CrtDumpMemoryLeaks() 检查尚未释放的内存。调用之前需要删除这两个指向的数据。

也就是说,您还有其他问题。

C++ 没有自动垃圾回收。您必须跟踪和管理您的内存分配或使用为您完成的类/代码。

考虑以下代码:

void iNeedALeak() {
void* p = new char[64];
strcpy(p, "Hello world");
std::cout << p << std::endl;
}

此代码进行了分配,并将其存储在“p”中。即使我们使用了几个函数的值,我们也从未存储过它。因此,它永远不会返回到系统。

代码中等待发生泄漏的一个示例是在运算符中>>

std::istream & operator>>(std::istream &is, Fruit *readFruit)
{
string tempString;
is >> tempString;
int size = tempString.length();
readFruit->name = new char[tempString.length()];

是的,在您的删除运算符中,您从名称中删除了[]。但这仅处理您的代码达到 ~Fruit 的情况,请考虑:

Fruit f;
cin >> f; // readFruit->name = new char[]..
cin >> f; // readFruit->name = new char[]...

此时,您不再存储原始值,也没有删除它。

您真正遇到的问题是您使用的是非常类似于 C 的方法。如果你打算用 C++ 编写它,你应该考虑使用 RAII ,例如,您可以使用 std::unique_ptr类。

TL;DR 不要公开原始指针,将它们封装在某些东西后面,以确保它们在超出范围或重新分配给它们时得到释放。

关于c++ - 如何阻止内存泄漏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19239609/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com