繁体   English   中英

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

[英]error Debug Assertion Failed - when deleting a dynamically allocated array

我一直在尝试完成课程作业,但是我一直收到似乎无法解决的错误。 调试断言失败我将问题(我认为)缩小到了析构函数。 如果我在行中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
}

这是驱动程序:

//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;
}

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

english = new char;

这会将english设置为一个动态分配的一个字符数组,然后立即将其设置为:

strcpy(english, " ");

这会将两个char -一个空格和一个\\0复制到仅一个字符的缓冲区中。 这在数组末尾运行,破坏了内存,并导致未定义的行为。

此外,在析构函数中:

 delete[] english; 

就其本身而言,这很好。 除了:

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

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

此外,展望未来,所示类违反了3规则 ,因此,很容易错误地使用它,从而导致进一步的错误。

总之,显示代码不正确处理动态分配的内存,犯沿着那些几个错误,从覆盖未分配的内存,以delete荷兰国际集团的内存,这是从来没有new摆在首位编辑。

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

问题是

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

然后将成员varialbe english分配给从数组test衰减的指针,该指针不是使用new[]动态分配的,因此无法delete[] ed,但这正是析构函数试图执行的操作。 因此UB。

根据代码的意图,您应该在Dictionary::setEnglish使用strcpystrncpy ,不要直接分配指针。

其他建议:

  1. 考虑一下“三规则” ,尤其是在使用原始指针(例如char* )时。

  2. 使用std :: string而不是C样式的字符串( char* )。

 `char test[5] = "test"; words[0].setEnglish(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并避免很多头痛。

问题是如何在setEnglish方法中设置值, 英语= eng的分配没有正确分配值,因此,如果使用strcpy可以解决:

采用:

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

你会得到正确的行为

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM