简体   繁体   English

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

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

I've been trying to complete a class assignment but I keep getting an error that I can't seem to resolve. 我一直在尝试完成课程作业,但是我一直收到似乎无法解决的错误。 Debug Assertion failed I've narrowed the problem (I think) to the destructor. 调试断言失败我将问题(我认为)缩小到了析构函数。 If I comment out the line delete[] english; 如果我在行中delete[] english; there is no error. 没有错误。 I've tried reading through other threads, but they haven't helped solve this. 我尝试阅读其他线程,但是它们并没有帮助解决此问题。 Here are the three files in the project (I took out all the rest of the code because the error still occurs with just this): 这是项目中的三个文件(我删除了所有其余代码,因为仅此错误仍然发生):

Here is the header file: 这是头文件:

//Dictionaty.h
#ifndef DICTIONARY_H
#define DICTIONARY_H

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

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


private:
    char *english;

};

#endif

Here is where the functions are: 这些功能在这里:

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

and this is the 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;
}

There are multiple bugs in the shown code. 显示的代码中存在多个错误。

english = new char;

This sets english to a dynamically-allocated array of one character, then immediately afterward: 这会将english设置为一个动态分配的一个字符数组,然后立即将其设置为:

strcpy(english, " ");

This copies two char s - a space and a \\0 - into a buffer of only one character. 这会将两个char -一个空格和一个\\0复制到仅一个字符的缓冲区中。 This runs off at the end of the array, corrupting memory, and results in undefined behavior. 这在数组末尾运行,破坏了内存,并导致未定义的行为。

Furthermore, in the destructor: 此外,在析构函数中:

 delete[] english; 

That, by itself, is fine. 就其本身而言,这很好。 Except: 除了:

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

As a result of this being called from main() , english gets set to a pointer to a buffer that was not allocated in dynamic scope. main()调用此方法的结果是, english被设置为指向未在动态范围内分配的缓冲区的指针。 As a result, the destructor will attempt to delete something that was not new ed. 结果,析构函数将尝试delete不是new This also results in undefined behavior. 这也会导致未定义的行为。

Furthermore, looking ahead, the shown class violates the Rule of 3 , and, as such, it's quite easily to use it incorrectly, resulting in further bugs. 此外,展望未来,所示类违反了3规则 ,因此,很容易错误地使用它,从而导致进一步的错误。

In conclusion, the shown code does not properly handle dynamically-allocated memory, committing several errors along the ones, from overwriting non-allocated memory, to delete ing memory that was never new ed in the first place. 总之,显示代码不正确处理动态分配的内存,犯沿着那些几个错误,从覆盖未分配的内存,以delete荷兰国际集团的内存,这是从来没有new摆在首位编辑。

You need to reread and study the chapter in your C++ book that talks about how to properly use dynamically-allocated memory. 您需要重新阅读和研究C ++书中有关如何正确使用动态分配的内存的章节。

The problem is 问题是

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

Then the member varialbe english is assigned to the pointer decayed from array test , which isn't dynamic allocated using new[] and then can't be delete[] ed, but it's exactly what the destructor is trying to do. 然后将成员varialbe english分配给从数组test衰减的指针,该指针不是使用new[]动态分配的,因此无法delete[] ed,但这正是析构函数试图执行的操作。 Therefore UB. 因此UB。

According to the intent of your code, you should use strcpy or strncpy in Dictionary::setEnglish , don't assign the pointer directly. 根据代码的意图,您应该在Dictionary::setEnglish使用strcpystrncpy ,不要直接分配指针。

Other suggestions: 其他建议:

  1. Consider about The Rule of Three , especially when you use raw pointers (such as char* ). 考虑一下“三规则” ,尤其是在使用原始指针(例如char* )时。

  2. Use std::string instead of C-style strings ( char* ). 使用std :: string而不是C样式的字符串( char* )。

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

Here test is allocated in the stack (there is no new there). 这里的测试分配在堆栈中(那里没有new )。 Then english = eng; 然后english = eng; will direct the pointer english toward it, you cannot delete from the stack. 会将english指针指向它,您不能从堆栈中delete

the fix: since you want your object to own the string, you should copy it . 解决方法:由于您希望对象拥有该字符串,因此应该将其复制

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
}

Finally, better use std::string and avoid lot of head-aches. 最后,最好使用std :: string并避免很多头痛。

The issue is how you set the value inside setEnglish method, the assigment of english = eng don't allocate the value in right way so, It can be fixed if you use strcpy instead: 问题是如何在setEnglish方法中设置值, 英语= eng的分配没有正确分配值,因此,如果使用strcpy可以解决:

Use: 采用:

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

you will get the right behaviour 你会得到正确的行为

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

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