检测到堆损坏(类方法)

时间:2018-12-23 17:23:17

标签: c++

通过运行此代码,我得到“检测到堆损坏”。

    E3Point E3Point::operator+(E3Point & t)
    {
    E3Point ret;
    ret.naziv = new char[strlen(naziv) + strlen(t.naziv) + 1];
    ret.naziv = strcat(naziv, t.naziv);
    ret.X = X + t.X;
    ret.Y = Y + t.Y;
    ret.Z = Z + t.Z;
    return ret;
    }

2 个答案:

答案 0 :(得分:3)

这两行导致 两个 问题:

ret.naziv = new char[strlen(naziv) + strlen(t.naziv) + 1];
ret.naziv = strcat(naziv, t.naziv);

第一个是std::strcpy附加到第一个参数提供的字符串。而且,如果您没有分配足够的内存,则strcat将超出写undefined behavior的范围。

第二个问题是strcat返回目的地,这意味着您正在有效地

ret.naziv = naziv;

,因此会丢失前一个new[]给定的原始指针,这会导致内存泄漏(以及其他可能的问题)。

简单的解决方案是停止使用旧的C样式,以null终止的字节字符串,而使用std::string

答案 1 :(得分:2)

在这一行:

ret.naziv = strcat(naziv, t.naziv);

您没有正确复制字符串。您正在将t.naziv复制到this->naviz而不是复制到ret.naziv。然后,您将返回的指针分配给ret.naviz,泄漏new所占用的内存,并使ret.navizthis->naziv都指向相同的内存。

您需要改用它:

strcpy(ret.naziv, naziv);
strcat(ret.naziv, t.naziv);

或者:

int len = strlen(naziv);
...
strcpy(ret.naziv, naziv);
strcpy(ret.naziv+len, t.naziv);

或者:

sprintf(ret.naziv, "%s%s", naziv, t.naziv);

如果还没有这样做,请确保遵循Rule of 3/5/0,否则您将遇到其他问题。

您实际上根本不应该手动管理内存。让标准库为您完成。如果nazivstd::string而不是char*,所有这些问题都会消失。