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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C ++奇怪的堆栈变量和函数行为相关的知识,希望对你有一定的参考价值。

我有一个String类与char* bufferunsigned int length

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

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

和一个析构函数

 ~String()

delete[] buffer;删除char数组。

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

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

int main() {
    String a("Hello");
    a = a.Replace('l', 'p');
    printf("%s
", 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
", b.char_ptr());
}

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

答案

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

以上是关于C ++奇怪的堆栈变量和函数行为的主要内容,如果未能解决你的问题,请参考以下文章

C++ 堆栈分配的对象赋值和析构函数调用

从 cython c 调用 python 函数时的奇怪行为

禁用优化的 c alloca 函数的奇怪汇编代码 - gcc 使用 DIV 和 IMUL 为常数 16,并转换?

奇怪的知识又增加了C语言函数返回1和返回0究竟哪个好?

我自己的堆栈类中的 C++ 奇怪行为

GLSL/C++:自定义着色器的默认行为