错误调试断言失败 - 删除动态分配的数组时

error Debug Assertion Failed - when deleting a dynamically allocated array

我一直在尝试完成一项 class 作业,但我总是收到一个我似乎无法解决的错误。 Debug Assertion failed 我已经将问题(我认为)缩小到析构函数。如果我注释掉 delete[] english; 行,则没有错误。我试过阅读其他线程,但他们没有帮助解决这个问题。这是项目中的三个文件(我把剩下的所有代码都去掉了,因为就这样还是会报错):

这是头文件:

//Dictionaty.h
#ifndef DICTIONARY_H
#define DICTIONARY_H

class Dictionary
{
public:
    Dictionary();
    ~Dictionary();

   void setEnglish(char*);
   char* getEnglish();


private:
    char *english;

};

#endif

这里是函数所在的地方:

//dictionary.cpp
#include <iostream>
#include "Dictionary.h"

using namespace std;

Dictionary::Dictionary()
{
    english = new char[20];


    strcpy(english, " ");
    //strcpy(french, " ");
}

Dictionary::~Dictionary()
{
    delete[] english; // problem is here (i think)

}

void Dictionary::setEnglish(char *eng)
{
    english = eng;
    cout << "the value of english in \"setEnglish()\" is: " << english << endl; //db
}

这是 driver:

//dictionaryDrv.cpp
#include <iostream>
#include "Dictionary.h"

using namespace std;

int main()
{
    Dictionary words[30];

    //readIn(words);
    char test[5] = "test";
    words[0].setEnglish(test);


    system("pause");
    return 0;
}
`char test[5] = "test";  words[0].setEnglish(test);`

这里test分配在栈中(那里没有new)。然后 english = eng; 会将指针 english 指向它,你不能从堆栈中 delete

修复:因为您希望您的对象拥有字符串,您应该复制它

void Dictionary::setEnglish(char *eng)
{
    delete[] english;
    english = new char[strlen(eng) + 1];
    strcpy(english, eng);
    cout << "the value of english in \"setEnglish()\" is: " << english << endl; //db
}

最后,更好地使用 std::string 避免很多头痛。

显示的代码中存在多个错误。

english = new char;

这会将 english 设置为动态分配的一个字符数组,然后紧接着:

strcpy(english, " ");

这会将两个 chars - 一个 space 和一个 [=16=] - 复制到只有一个字符的缓冲区中。这会在数组末尾运行,破坏内存,并导致未定义的行为。

此外,在析构函数中:

 delete[] english; 

这本身就很好。除了:

void Dictionary::setEnglish(char *eng)
{
    english = eng;

作为从 main() 调用的结果,english 被设置为指向未在动态范围内分配的缓冲区的指针。结果,析构函数将尝试 delete 未被 new 编辑的内容。这也会导致未定义的行为。

此外,展望未来,显示 class violates the Rule of 3,因此,很容易错误地使用它,导致更多错误。

总而言之,显示的代码没有正确处理动态分配的内存,犯了几个错误,从覆盖未分配的内存到 deleteing 从未 new 的内存排在第一位。

您需要重新阅读和研究 C++ 书中讨论如何正确使用动态分配内存的章节。

问题是

char test[5] = "test";
words[0].setEnglish(test);

然后成员varialbe english被分配给数组test衰减的指针,它不是使用new[]动态分配的,因此不能delete[]ed,但这正是析构函数试图做的。因此UB.

根据你的代码意图,你应该在Dictionary::setEnglish中使用strcpystrncpy,不要直接赋值指针。

其他建议:

  1. 考虑一下The Rule of Three,尤其是当你使用裸指针的时候(比如char*)。

  2. 使用 std::string 代替 C 风格字符串 (char*)。

问题是你如何在 setEnglish 方法中设置值,english = eng 的分配没有以正确的方式分配值,如果你可以解决使用 strcpy 代替:

使用:

    void Dictionary::setEnglish(char *eng) {
        strcpy(english,eng);
        cout << "the value of english in \"setEnglish()\" is: " << english << endl; 
}

你会得到正确的行为