gpt4 book ai didi

c++ - 内存分配 - 正确使用 delete

转载 作者:行者123 更新时间:2023-11-30 00:38:34 24 4
gpt4 key购买 nike

我所有的程序都因为 delete [] meanings;, delete [] meanings;, delete [] temp_meaning; 而崩溃,当我删除这 3 行它工作正常,所以可能我错误地使用了删除...有人可以在这里启发我吗?

#include <iostream>
#include <string>
#include <cstring>
using namespace std;

class Expression {

char *word_with_several_meanings; // like "bank", "class"
char **meanings; // a pointer to a pointer stores all meanings
int meanings_ctr; // meanings counter

//-----------FUNCTIONS------------------------------------------------
public:
void word(const char* = NULL );
void add_meaning(char * = NULL);
char* get_word();
int get_total_number_of_meanings();
char* get_meaning(int meanx = 0);
Expression(int mctr = 0); // CTOR
~Expression(); // DTOR
};

Expression::Expression(int mctr ) {
meanings_ctr = mctr; // Setting the counter to 0
meanings = new char * [meanings_ctr]; // Allocate Space for meanings
}

Expression::~Expression() {

while(meanings_ctr-->0){
delete meanings[meanings_ctr];
}
delete [] meanings; // Deleting the memory we allocated
delete [] word_with_several_meanings; // Deleting the memory we allocated
}

void Expression::word(const char *p2c )
{

word_with_several_meanings = new char[strlen(p2c)+1];
// copy the string, DEEP copy
strcpy(word_with_several_meanings, p2c);
}

void Expression::add_meaning( char * p2c)
{

//meanings[ meanings_ctr ] = new char [strlen(p2c) + 1];
//strcpy(meanings[ meanings_ctr++ ] , p2c);
// temp
if (meanings_ctr < 1){
meanings[ meanings_ctr ] = new char [strlen(p2c) + 1];
strcpy(meanings[ meanings_ctr++ ] , p2c);
}
else {
int temp_ctr;
char **temp_meaning;
temp_meaning = new char * [meanings_ctr-1];
for(temp_ctr =0; temp_ctr<meanings_ctr;temp_ctr++){
temp_meaning[temp_ctr] = new char [strlen(meanings[ temp_ctr ]) + 1];
strcpy(temp_meaning[temp_ctr], meanings[ temp_ctr ]);
}
for (temp_ctr =0; temp_ctr<meanings_ctr;temp_ctr++){
delete meanings[temp_ctr];

}
delete [] meanings;

meanings = new char * [meanings_ctr];
for(temp_ctr =0; temp_ctr<meanings_ctr;temp_ctr++){
meanings[ temp_ctr ] = new char [strlen(temp_meaning[temp_ctr]) + 1];
strcpy(meanings[ temp_ctr ], temp_meaning[temp_ctr]);
}
meanings[ meanings_ctr ] = new char [strlen(p2c) + 1];
strcpy(meanings[ meanings_ctr ] , p2c);
for (temp_ctr =0; temp_ctr<meanings_ctr;temp_ctr++){
delete temp_meaning[temp_ctr];
}
delete [] temp_meaning;
meanings_ctr++;
}


}

char * Expression::get_meaning( int meanx )
{

return *(meanings+meanx);

}

char * Expression::get_word()
{

return word_with_several_meanings;

}

int Expression::get_total_number_of_meanings()
{
return meanings_ctr;
}


int main(void) {
int i;
Expression expr;
expr.word("bank");
expr.add_meaning("a place to get money from");
expr.add_meaning("b place to sit");
expr.add_meaning("4 letter word");
expr.add_meaning("Test meaning");
cout << expr.get_word() << endl;

for(int i = 0; i<expr.get_total_number_of_meanings(); i++)
cout << " " << expr.get_meaning(i) << endl;
Expression expr2;
expr2.word("class");
expr2.add_meaning("a school class");
expr2.add_meaning("a classification for a hotel");
expr2.add_meaning("Starts with C");
cout << expr2.get_word() << endl;
for( i = 0; i<expr2.get_total_number_of_meanings(); i++)
cout << " " << expr2.get_meaning(i) << endl;

Expression expr3;
expr3.word("A very long test");
char str[] = "Meaning_ ";
for(int kx =0; kx<31; kx++){
str[8] = ('A'+kx);
expr3.add_meaning(str);
}

cout << expr3.get_word() << endl;
for( int i = 0; i<expr3.get_total_number_of_meanings(); i++)
cout << " " << expr3.get_meaning(i) << endl;
return 0;
}

最佳答案

此程序显示出来自以下语句的内存损坏迹象:

    meanings_ctr = mctr;    // Setting the counter to 0
meanings = new char * [meanings_ctr]; // Allocate Space for meanings

    meanings = new char * [meanings_ctr];

由于 add_meaning() 包含以下代码:

if (meanings_ctr < 1){
meanings[ meanings_ctr ] = new char [strlen(p2c) + 1];

你实际上写在 meanings[0],而你为它分配了 0 个字节。由于 C 中的索引从 0 开始,对于具有最高索引的数组 max_index你需要分配max_index+1元素。对于带有 max_index = 0 的数组你需要分配 1 个元素。

换句话说你需要分配meanings = new char * [meanings_ctr + 1]而不是 new char * [meanings_ctr] , 和 temp_meaning = new char * [meanings_ctr]而不是 new char * [meanings_ctr - 1] .

至于delete的用途和 delete[]一般规则是用 new 分配的内容应该用 delete 释放以及分配给 new[] 的内容应该用 delete[] 销毁.上面有一个线程:delete vs delete[] operators in C++ .在 how does delete know it is an array 的答案中可以找到一些很好的背景。 .

下面是如何在不使用任何昂贵的工具或难以学习的工具的情况下调试程序。

如果像这样将调试打印添加到构造函数和析构函数中:

Expression::Expression(int mctr ) {
meanings_ctr = mctr; // Setting the counter to 0
meanings = new char * [meanings_ctr]; // Allocate Space for meanings
cout << "[debug] allocated " << sizeof(char*)*meanings_ctr << " bytes @" <<
hex << meanings << dec << endl;
}

Expression::~Expression() {
while(meanings_ctr-- > 0){
// if(meanings[meanings_ctr]) delete [] (meanings[meanings_ctr]);
}
cout << "[debug] to deallocate @" << hex << meanings << dec << endl;
// delete [] meanings; // Deleting the memory we allocated
// delete [] word_with_several_meanings; // Deleting the memory we allocated
}

同样在 add_meaning() 中,你会得到

[debug] allocated 0 bytes @0x804c008
[debug] to deallocate @0x804c008
[debug] allocated 4 bytes @0x804c078
...
[debug] allocated 120 bytes @0x804fa78
[debug] to deallocate @0x804fa78
[debug] to deallocate @0x804c260
[debug] to deallocate @0x804c150

这里看起来令人担忧的是allocated 0 bytes .由于 add_meanings() 中的代码包含:

if (meanings_ctr < 1){
meanings[ meanings_ctr ] = new char [strlen(p2c) + 1];

它使用内存 @ meanings[0]未分配并导致腐败。

这里是所有累积的变化供引用:

25c25
< meanings = new char * [meanings_ctr]; // Allocate Space for meanings
---
> meanings = new char * [meanings_ctr + 1]; // Allocate Space for meanings
30,31c30,31
< while(meanings_ctr-->0){
< delete meanings[meanings_ctr];
---
> while(meanings_ctr-- > 0){
> delete [] meanings[meanings_ctr];
58c58
< temp_meaning = new char * [meanings_ctr-1];
---
> temp_meaning = new char * [meanings_ctr ];
64c64
< delete meanings[temp_ctr];
---
> delete [] meanings[temp_ctr];
69c69
< meanings = new char * [meanings_ctr];
---
> meanings = new char * [meanings_ctr + 1];
76,77c76,77
< for (temp_ctr =0; temp_ctr<meanings_ctr;temp_ctr++){
< delete temp_meaning[temp_ctr];
---
> for (temp_ctr =0; temp_ctr<meanings_ctr;temp_ctr++){
> delete [] temp_meaning[temp_ctr];

关于c++ - 内存分配 - 正确使用 delete,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10397544/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com