2015-06-22 78 views
1

我在程序结束时删除对象时出现问题。这是一个C++课程,所以我们不允许使用字符串类(还)。我有一个武器类为武器生成一个名字,这个名字被char* result = new char[len]实例化,然后返回给构造函数。在析构函数中,我使用delete[] this->name删除名称对象。尝试删除对象时检测到堆损坏(C++)

问题:

当我运行我的程序,一切都正常运行,直到程序涉及到程序的删除部分。然后我得到这个错误信息:

调试错误!

计划:...路径编程...

堆损坏。结果:在正常0x0100B918块(#198)之后。 CRT 检测到应用程序在缓冲区结束堆 后写入内存。

(按重试来调试应用程序)

我曾尝试更换用delete [],反之亦然删除,并没有什么区别。

任何人都可以发现我想错的地方吗?

main.cpp中:

int _tmain(int argc, _TCHAR* argv[]) { 

    // ... code ... 

    Weapon* weapon = new Weapon(); 

    // ... code ... 

    delete weapon; 

} 

Weapon.cpp:

Weapon::Weapon() { 
    this->name = this->generateName(); 
    // more properties... 
} 

Weapon::~Weapon() { 
    delete[] this->name; 
    this->name = nullptr; 
} 

char* Weapon::generateName() { 
    int pr, tp, su; // random variables for picking prefix, type and suffix 

    const char *prefix[10] = { // ... a bunch of names ... }; 
    const char *type[10] = { // ... a bunch of names ... }; 
    const char *suffix[10] = { // ... a bunch of names ... }; 

    pr = rand() % 9; 
    tp = rand() % 9; 
    su = rand() % 9; 

    int len = strlen(prefix[pr]) + strlen(type[tp]) + strlen(suffix[su]) + 1; 
    char *result = new char[len](); 
    strcpy(result, prefix[pr]); 
    strcat(result, " "); 
    strcat(result, type[tp]); 
    strcat(result, " "); 
    strcat(result, suffix[su]); 

    return result; 
} 
+2

你很可能会溢出结果 - 写入超过分配。 –

+0

“这是为了C++课程,所以我们不允许使用字符串类(还)。”叹。 CS的迷人之处在继续。不要学习最有用的语言功能,永远不要提及使用调试器和调试技术 – pm100

回答

5

你忘了该字符串的空间在分配房间:

int len = strlen(prefix[pr]) + strlen(type[tp]) + strlen(suffix[su]) + 1; 

应该是:

int len = strlen(prefix[pr]) + 1 + strlen(type[tp]) + 1 + strlen(suffix[su]) + 1; 

这两个额外的字符会覆盖超出分配块的内存,这会占用检测到的堆损坏。

+0

哇...感谢了很多发现:) –

+1

另外,使用std :: string,所以你不必担心这些错误。 虽然由于std :: string没有“释放”功能,你将不得不改变generateName的签名 – KABoissonneault

+0

是的,我很乐意使用字符串类。希望下一项任务能让我们使用它。 –