错误调试断言失败 - 删除动态分配的数组时
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, " ");
这会将两个 char
s - 一个 space 和一个 [=16=]
- 复制到只有一个字符的缓冲区中。这会在数组末尾运行,破坏内存,并导致未定义的行为。
此外,在析构函数中:
delete[] english;
这本身就很好。除了:
void Dictionary::setEnglish(char *eng)
{
english = eng;
作为从 main()
调用的结果,english
被设置为指向未在动态范围内分配的缓冲区的指针。结果,析构函数将尝试 delete
未被 new
编辑的内容。这也会导致未定义的行为。
此外,展望未来,显示 class violates the Rule of 3,因此,很容易错误地使用它,导致更多错误。
总而言之,显示的代码没有正确处理动态分配的内存,犯了几个错误,从覆盖未分配的内存到 delete
ing 从未 new
的内存排在第一位。
您需要重新阅读和研究 C++ 书中讨论如何正确使用动态分配内存的章节。
问题是
char test[5] = "test";
words[0].setEnglish(test);
然后成员varialbe english
被分配给数组test
衰减的指针,它不是使用new[]
动态分配的,因此不能delete[]
ed,但这正是析构函数试图做的。因此UB.
根据你的代码意图,你应该在Dictionary::setEnglish
中使用strcpy
或strncpy
,不要直接赋值指针。
其他建议:
考虑一下The Rule of Three,尤其是当你使用裸指针的时候(比如char*
)。
使用 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;
}
你会得到正确的行为
我一直在尝试完成一项 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, " ");
这会将两个 char
s - 一个 space 和一个 [=16=]
- 复制到只有一个字符的缓冲区中。这会在数组末尾运行,破坏内存,并导致未定义的行为。
此外,在析构函数中:
delete[] english;
这本身就很好。除了:
void Dictionary::setEnglish(char *eng)
{
english = eng;
作为从 main()
调用的结果,english
被设置为指向未在动态范围内分配的缓冲区的指针。结果,析构函数将尝试 delete
未被 new
编辑的内容。这也会导致未定义的行为。
此外,展望未来,显示 class violates the Rule of 3,因此,很容易错误地使用它,导致更多错误。
总而言之,显示的代码没有正确处理动态分配的内存,犯了几个错误,从覆盖未分配的内存到 delete
ing 从未 new
的内存排在第一位。
您需要重新阅读和研究 C++ 书中讨论如何正确使用动态分配内存的章节。
问题是
char test[5] = "test";
words[0].setEnglish(test);
然后成员varialbe english
被分配给数组test
衰减的指针,它不是使用new[]
动态分配的,因此不能delete[]
ed,但这正是析构函数试图做的。因此UB.
根据你的代码意图,你应该在Dictionary::setEnglish
中使用strcpy
或strncpy
,不要直接赋值指针。
其他建议:
考虑一下The Rule of Three,尤其是当你使用裸指针的时候(比如
char*
)。使用 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;
}
你会得到正确的行为