使用删除时堆损坏

时间:2019-12-24 00:09:27

标签: c++

我有一个MultiString类,其中包含一些方法。

我正在努力删除析构函数中的字符串数组,但是我得到了堆损坏。

这是我的课程(某些方法被删减了)

class MultiString {
public:
    //constructor destructor
    MultiString(int);
    ~MultiString();

    //methods
    void Setat(int nindex, const char* str);

    //attributes

    char** buf;//pointer to vector
    int str_nmb;//strings number
};

构造函数代码:

MultiString::MultiString(int number)
{
    str_nmb = number;
    buf = new char* [number];
    for (int i = 0; i < number; i++) buf[i] = NULL;
}

设置代码(用于设置数组中的字符串):

void MultiString::Setat(int nindex, const char* str)
{
    if (nindex<0 || nindex>str_nmb || str == NULL) {
        std::cout << "gg";
        return;
    }
    char* tmp = new char[strlen(str)+1];
    if (tmp == NULL) return;
    if (buf[nindex] != NULL) delete buf[nindex]; //here delete works fine
    buf[nindex] = tmp;
    strcpy_s(buf[nindex], strlen(buf[nindex]), str);
    std::cout << buf[nindex]<< std::endl;
}

析构函数代码:

MultiString::~MultiString()
{
    for (int i = 0; i < str_nmb; i++)
         delete buf[i]; // heap corruption here
    delete buf;
}

还有我的main()

int main()
{
    MultiString* ms = new MultiString(3);
    ms->etat(0, "qwerty");
    ms->Setat(1, "asdfgh");
    ms->Setat(2, "zxcvbn");
    delete ms;
    return 0;
}

1 个答案:

答案 0 :(得分:4)

char* tmp = new char[strlen(str)+1];
// ...
buf[nindex] = tmp;
strcpy_s(buf[nindex], strlen(buf[nindex]), str);

buf[nindex]指向刚分配的但未初始化的存储区。调用strlen是未定义的行为,很可能会破坏您的堆。您可能想改为致电strlen(str)


除此之外,您还会犯其他错误:

  • 0/3/5规则已损坏。
  • delete,其中需要delete[]
  • 错误的边界检查(nindex>str_nmb
  • Multistring(-5)呢?
  • if (tmp == NULL) return; ...不,您不应该静音错误。抛出异常或其他东西。

也..为什么strcpy_s呢?使用std::strncpy ...至少保证可以使用!确保复制的C字符串以null结尾!