C++ C++;通过引用传递的方法参数-内存问题

C++ C++;通过引用传递的方法参数-内存问题,c++,memory,pass-by-reference,C++,Memory,Pass By Reference,假设 我知道在runningMethod退出时,str将自动解除分配;在这种情况下,C++如何删除旧数据(“ABC”)? 谢谢 吉尔。“ABC”在您说=“123”时被覆盖 在内部,字符串是一个字符数组。开始时,它创建了一个新的缓冲区,其中包含{'a','B','C','\0'}。分配时,它只在'A'上写'1',依此类推 当它破坏时,它删除了缓冲区。确切的细节取决于CString的实现,但重要的一点是,您不必担心分配和解除分配,因为类会为您处理它。同样的情况也会发生,就像您编写: void pro

假设

我知道在runningMethod退出时,str将自动解除分配;在这种情况下,C++如何删除旧数据(“ABC”)? 谢谢

吉尔。

“ABC”
在您说
=“123”
时被覆盖

在内部,字符串是一个字符数组。开始时,它创建了一个新的缓冲区,其中包含
{'a','B','C','\0'}
。分配时,它只在
'A'
上写
'1'
,依此类推


当它破坏时,它删除了缓冲区。

确切的细节取决于
CString
的实现,但重要的一点是,您不必担心分配和解除分配,因为类会为您处理它。

同样的情况也会发生,就像您编写:

void proc(CString& str)
{
  str = "123";
}

void runningMethod()
{
  CString str="ABC";
  proc(str);
}

在大多数情况下,当您在
proc()
中执行作业时,“ABC”将被释放。这通常在重载运算符方法中完成。例如 你们有这样一个例子,过载是什么样子的

CString foo = "ABC";
foo = "123";

这里有几件事要记住。首先,类的运算符=通常会在分配新数据之前删除它用来引用的任何内容。当然,这并不完全正确,通常情况下,聪明的开发人员会通过首先创建传入类的副本,然后将当前数据与新的临时数据交换来实现operator=,新的临时数据现在拥有所有权并将其删除。但要记住的重要部分是,在运算符=函数存在之前,通常情况下,旧数据已被丢弃

要记住的另一件事是“ABC”是字符串文字。该标准并没有真正定义如何存储它们,它只是说明了允许某些常规实现的限制。通常,该字符串文本在程序数据中显示为只读元素。在这种情况下,只要程序的映像加载到内存中(当它基本上运行时),它就永远不会被删除。这就是为什么这样的代码是UB的全部原因:


void f()
{
char*x=“hello”//指向字符串文本。
x[0]=‘H’;
}

//正确的实施方法是: void f() { char x[]=“hello”//保留一个包含6个字符的数组,并复制字符串文字内容。 x[0]=‘H’; }

那“覆盖”会调用“ABC”字符串的析构函数吗?@gilbertc:你是什么意思?字符串有一个内部缓冲区。它保持“ABC”,被修改为保持“123”,然后被删除。@gilbertc:取决于运算符=的定义。我不确定的是,CString是否是char*类型的别名。。。如果我知道我能给出一个更好的答案,这取决于你的类型。它是如何实现的?@struppi:CString是Microsoft MFC库中包含的字符串类。请注意,标准字符串是
std::string
,而不是
CString
。为什么不打开CString::operator=的源代码并查看?删除前无需检查null。
String& String::operator= (const String& other)
{
        char* otherdata = other.data;
        char* olddata = data;
        if (otherdata != 0)
        {
                data = new char[other.length+1];
                length = other.length;
                memcpy(data,otherdata,other.length+1);
        }
        else
        {
                data = 0;
                length = 0;
        }
        if (olddata != 0)
        {
                delete[] olddata;
        }
    return *this;
}

void f()
{
  char * x = "hello"; // points to a string literal.
  x[0] = 'H';
}

// correct implementation is: void f() { char x[] = "hello"; // reserved an array of 6 characters and copies string literal content. x[0] = 'H'; }