具有堆栈变量和函数的C ++怪异行为

时间:2018-06-26 18:22:33

标签: c++ variables stack rule-of-three

我有一个String类,其中包含一个char* buffer和一个unsigned int length

字符串类具有两个构造函数:

String(const char* str);
String(const String& other);

和一个析构函数

 ~String()

使用delete[] buffer;删除char数组。

两个构造函数都创建一个新的缓冲区数组buffer = new char[size];,并用来自const char* stringconst String& other的正确数据填充它。字符串缓冲区以null结尾。

在我的主要功能中,我有以下代码:

int main() {
    String a("Hello");
    a = a.Replace('l', 'p');
    printf("%s\n", a.char_ptr());
}

我希望它可以将Heppo打印到控制台。 replace函数采用两个字符,其中第一个出现的所有字符均被第二个替换。它返回一个全新的String

String String::Replace(const char& a, const char& b) {
    const char* buf = ...;
    // Do the replacement and store the result in buf

    String s(buf);
    delete[] buf;
    return s;
}

据我了解,编译器将返回局部变量s的副本。因此,a中的main()变量应该是完全合法的String。但是控制台的输出看起来像¦¦¦¦¦¦¦¦¦¦,看起来像是未初始化的内存。

甚至更怪异,当我将主要方法更改为:

int main() {
    String a("Hello");
    String b = a.Replace('l', 'p');
    printf("%s\n", b.char_ptr());
}

我看到了预期的输出。经过大量阅读后,我不知道解决方案,因为这个问题确实很难在google / stackoverflow搜索中描述。

1 个答案:

答案 0 :(得分:0)

主要问题是违反了big 3的规则。由于您拥有微不足道的析构函数,因此还必须定义一个复制构造函数和一个赋值运算符。 您可以在实现上述功能时考虑“复制交换”的习惯用法。 在存在非平凡的析构函数的情况下未定义两者中的任何一个都会导致资源(此示例中的内存)泄漏。