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