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

C++ weird behaviour with stack variables and functions

我有一个 String class,一个 char* buffer 和一个 unsigned int length

字符串class有两个构造函数:

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

和一个析构函数

 ~String()

删除带有 delete[] buffer; 的字符数组。

两个构造函数都创建了一个新的缓冲区数组 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 函数采用两个字符,其中所有出现的第一个字符都被第二个字符替换。它 return 是一个全新的 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;
}

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

更奇怪的是,当我将我的主要方法更改为:

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

我看到了预期的输出。大量阅读后我无法找到解决方案,因为这个问题在 google/Whosebug 搜索中很难描述。

主要问题是违反了big 3的规则。因为你有一个none trivial destructur,你还必须定义一个复制构造函数和一个赋值运算符。 在实现上述功能时,您可能会考虑复制交换习惯用法。 在 none-trivial 析构函数存在的情况下不定义两者中的任何一个,导致资源(此示例中的内存)泄漏。