从char数组释放内存

时间:2018-10-05 21:37:48

标签: c++

获得错误(或可能是异常)的声音,但没有错误弹出窗口,因此无法理解问题所在。使用调试器后,意识到错误来自析构函数。所以我得到的结果是“八月”,但是程序在那之后不会停止工作。假设问题出在释放内存上。预先感谢。

#include <iostream>
using namespace std;
class B_class {
    char *p;
public:
    void put_author(char *p) {
        this->p = new char[strlen(p)];
        for (int i = 0; i < strlen(p) + 1; i++)
            *(this->p + i) = *(p + i);          
    }
    void show_author() {
        for (int i = 0; i < strlen(p) + 1; i++)
            cout << *(p + i);
        cout << endl;
    }
    ~B_class() {
        if (*p) {
            delete[] p;
            p = nullptr;
        }
    }
};

int main() {
    B_class B;
    B.put_author("August");
    B.show_author();
    return 0;
}

1 个答案:

答案 0 :(得分:1)

this->p = new char[strlen(p)];

您已经分配了strlen(p)个字符。

for (int i = 0; i < strlen(p) + 1; i++)
    *(this->p + i) = *(p + i);

您将strlen(p) + 1个字符写入数组。这比分配的数组的长度多一。无法访问超出其界限的数组的行为。

您可以通过分配足够大的缓冲区来解决此问题。


如果您创建了B_class的实例,但是从不调用put_author,那么您将在未初始化的指针上调用delete[] p。该行为是不确定的。

您可以通过在构造函数中初始化p成员来解决此问题。要么是nullptr,要么是使用new[]分配的一些缓冲区。


if (*p) {
    delete[] p;

只有p不是一个空字符串,您才删除它。因此,如果您执行B.put_author("");,则内存将泄漏。

您可以通过删除if来解决此问题。


在您的示例中,您碰巧没有执行此操作,但是,如果制作了B_class实例的任何副本,则这些实例的析构函数将尝试删除相同的缓冲区,这将导致未定义的行为。

您可以通过遵循零/三/五的规则来解决此问题。传统方法是使用std::string并摆脱析构函数。