为什么我的堆已损坏?

发布于 2024-09-24 18:50:42 字数 1226 浏览 1 评论 0原文

我收到错误 - 堆损坏,无法弄清楚原因。

我的基地:

h:

class Base
{
public :
    Base(char* baseName, char* cityName);
    virtual ~Base();

    list<Vehicle*>::const_iterator GetEndList();
    void PrintAllVehicles(ofstream &ResultFile) const;
    char* GetBaseName() const;
    char* GetLocation() const;
    void InsertNewVehicleToBase(Vehicle* newVehicle);
    list<Vehicle*>::const_iterator FindVehicle(char* id);
    void RemoveVehicle (list<Vehicle*>::const_iterator beg);



 private:
    char* m_name;
    char* m_location;
    list<Vehicle*> m_baseVehicles;

};  

cpp:

Base::Base(char* baseName, char* cityName)
{
    m_name = new char [strlen(baseName)+1];
    strcpy(m_name, baseName);
    m_location = new char [strlen(cityName)+1];
    strcpy(m_location, cityName);
}

Base::~Base()
{
    delete [] m_name;
    delete [] m_location;
    //m_baseVehicles.clear();
}

军队析构函数:

Army::~Army()
{
    list<Base*>::iterator baseIter = m_basesList.begin();
    for (baseIter ; baseIter != m_basesList.end() ; ++baseIter)
        delete (*baseIter);
    m_basesList.clear();
 }  

我做错了什么?

I'm getting an error - heap corruption, can't figure out why.

My base :

h:

class Base
{
public :
    Base(char* baseName, char* cityName);
    virtual ~Base();

    list<Vehicle*>::const_iterator GetEndList();
    void PrintAllVehicles(ofstream &ResultFile) const;
    char* GetBaseName() const;
    char* GetLocation() const;
    void InsertNewVehicleToBase(Vehicle* newVehicle);
    list<Vehicle*>::const_iterator FindVehicle(char* id);
    void RemoveVehicle (list<Vehicle*>::const_iterator beg);



 private:
    char* m_name;
    char* m_location;
    list<Vehicle*> m_baseVehicles;

};  

cpp :

Base::Base(char* baseName, char* cityName)
{
    m_name = new char [strlen(baseName)+1];
    strcpy(m_name, baseName);
    m_location = new char [strlen(cityName)+1];
    strcpy(m_location, cityName);
}

Base::~Base()
{
    delete [] m_name;
    delete [] m_location;
    //m_baseVehicles.clear();
}

army destructor :

Army::~Army()
{
    list<Base*>::iterator baseIter = m_basesList.begin();
    for (baseIter ; baseIter != m_basesList.end() ; ++baseIter)
        delete (*baseIter);
    m_basesList.clear();
 }  

What am I doing wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

[浮城] 2024-10-01 18:50:42

您所显示的代码没有明显的错误,因此错误很可能出在您未显示的代码中。

对我来说,最直接可疑的事情是 Base 类拥有两个指针,并且没有定义复制构造函数或赋值运算符。这意味着,如果您复制 Base 对象,最终将得到两个指向相同数据的 Base 对象,并且当它们析构时,它们将删除它两次,导致堆损坏。

Army 类也可能有这个问题(因为它拥有几个 Base 指针),但是您没有显示该类的定义,因此不清楚是否它是否有复制构造函数和赋值运算符。

最后,您还没有显示 Base 对象的分配位置。它们是否有可能被传递到 Army 对象中,并在 Army 对象之外的某个位置被删除?或者,Army 对象包含的 Base* 可能引用了堆栈上不应删除的对象?

There's nothing obviously wrong with the code you've shown, so chances are that the error is in code you haven't shown.

The most immediately suspicious thing to me is that the Base class owns two pointers and does not have a copy constructor or assignment operator defined. This means that should you ever copy a Base object, you will end up with two Base objects pointing to the same data, and when they destruct, they will delete it twice, causing heap corruption.

The Army class may also have this problem as well (since it owns several Base pointers), but you don't show the definition of the class, so it's not obvious whether it has a copy constructor and assignment operator or not.

Finally, you haven't shown where the Base objects are being allocated. Is it possible that they are being passed into an Army object and also deleted somewhere outside the Army object? Or perhaps the Base* contained by the Army object are referring to objects on the stack that should not be deleted?

半世晨晓 2024-10-01 18:50:42

此代码的可见问题:

  • 使用 char* 而不是 std::string 需要手动内存管理
  • 使用
    STL 容器中的原始指针
    清理代码过于复杂
  • 使用 CRT 进行字符串操作使
    C++“代码味道”

Visible problems with this code:

  • use of char* not std::string requires manual memory management
  • Use of
    raw pointers in STL containers
    overcomplicates cleanup code
  • use of CRT for string manipulation is
    a C++ 'code smell'
一个人的夜不怕黑 2024-10-01 18:50:42

给出的代码片段没有任何问题。
但使用这种代码,多次删除的可能性很高,我的意思是两次删除内存块,这会导致堆损坏。

Nothing wrong with the piece of code given.
But with this kind of code, there is a high possiblity of mutiple deletion, I mean deletin a memory block twice which leads to heap corruption.

江湖彼岸 2024-10-01 18:50:42

您没有发布有问题的代码部分,因为所有这些看起来都很正常。然而,它有很多 const 正确性问题:

Base(char* baseName, char* cityName);

字符串应该作为 const char* 传递,除非它们被修改。

virtual ~Base();

不知道这是否需要虚拟;看不到它的子类是什么。

list<Vehicle*>::const_iterator GetEndList();

应该是一个 const 方法,因为它是一个 const_iteratorlist::const_iterator GetEndList() const;

char* GetBaseName() const;
char* GetLocation() const;

这些应该返回 const char*,因为您的代码未设置为处理正在更改的名称和位置。

list<Vehicle*>::const_iterator FindVehicle(char* id);

同样,应该是一个 const 方法: list::const_iterator FindVehicle(char* id) const;

Base::~Base()
{
    delete [] m_name;
    delete [] m_location;
    //m_baseVehicles.clear();
}

你不需要 m_baseVehicles.clear();因为它无论如何都会在析构函数之后发生。但是,如果其他地方没有引用这些车辆,则需要将其删除,否则会发生泄漏。

军队破坏者:

“破坏者”。其余的陆军在哪里?

Army::~Army()
{
    list<Base*>::iterator baseIter = m_basesList.begin();
    for (baseIter ; baseIter != m_basesList.end() ; ++baseIter)
        delete (*baseIter);
    m_basesList.clear();
 }  

同样,您不需要 m_basesList.clear();

You didn't post the part of the code that has the problem, because all that looks pretty normal. However, it's got a lot of const-correctness problems:

Base(char* baseName, char* cityName);

Strings should be passed as const char* unless they are being modified.

virtual ~Base();

No idea if this needs to be virtual; can't see what its subclasses are.

list<Vehicle*>::const_iterator GetEndList();

Should be a const method, since it's a const_iterator: list<Vehicle*>::const_iterator GetEndList() const;

char* GetBaseName() const;
char* GetLocation() const;

These should return const char*, since your code is not set up to handle the name and location being changed.

list<Vehicle*>::const_iterator FindVehicle(char* id);

Again, should be a const method: list<Vehicle*>::const_iterator FindVehicle(char* id) const;

Base::~Base()
{
    delete [] m_name;
    delete [] m_location;
    //m_baseVehicles.clear();
}

You don't need m_baseVehicles.clear(); because it happens anyway right after the destructor. However, you need to delete the vehicles if they aren't referenced elsewhere, or you'll get a leak.

army distructor :

"destructor". And where is the rest of Army?

Army::~Army()
{
    list<Base*>::iterator baseIter = m_basesList.begin();
    for (baseIter ; baseIter != m_basesList.end() ; ++baseIter)
        delete (*baseIter);
    m_basesList.clear();
 }  

Again, you don't need m_basesList.clear();.

2024-10-01 18:50:42

我没有看到任何问题。正如马特·凯恩所说,它是如何填充的?

I don't see any problem. Just as Matt Kane said, how does it get populated?

时光匆匆的小流年 2024-10-01 18:50:42

堆损坏是由于将比分配给该单元的内存更多的数据复制到已分配的堆单元中。堆单元的开头和结尾包含的数据在被覆盖时将被报告为堆损坏。

您还没有发布所有代码,我在您发布的代码中看不到问题,但我建议使用像 Valgrind 这样的内存工具来帮助您诊断问题。

Heap corruptions come from copying more data into an allocated heap cell than the memory allocated to the cell. The beginning and end of heap cells contain data than when overwritten will be reported as a heap corruption.

You have not posted all the code and I cannot see a problem in the code you have posted but I would advise using a memory tool like Valgrind to help you diagnose the problem.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文