首页 > 解决方案 > 堆栈变量和函数的 C++ 奇怪行为

问题描述

我有一个String带有 achar* buffer和 a的课程unsigned int length

string 类有两个构造函数:

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

和一个析构函数

 ~String()

删除 char 数组delete[] buffer;

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

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

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变量 inmain()应该是完全合法的String. 但是控制台的输出看起来像¦¦¦¦¦¦¦¦¦¦,看起来像未初始化的内存。

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

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

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

标签: c++variablesstackrule-of-three

解决方案


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


推荐阅读