1

我试图提高我的 C++ 技能。我有2个功能:

concat_HeapVal()按值
concat_HeapRef()返回输出堆变量 按引用返回输出堆变量

当 main() 运行时,它将在堆栈上,s1 和 s2 将在堆栈上,我仅通过 ref 传递值,并且在以下每个函数中,我在堆上创建一个变量并将它们连接起来。

当 concat_HeapVal() 被调用时,它会返回正确的输出。
当 concat_HeapRef() 被调用时,它会返回一些内存地址(错误的输出)。为什么?

我在这两个函数中都使用了 new 运算符。因此它在堆上分配。
因此,当我通过引用返回时,即使我的 main() 堆栈内存超出范围,堆仍然有效。

所以留给操作系统清理内存。对?

string& concat_HeapRef(const string& s1, const string& s2)
{

    string *temp = new string();
    temp->append(s1);

    temp->append(s2);
    return *temp;
}


string* concat_HeapVal(const string& s1, const string& s2)
{

    string *temp = new string();
    temp->append(s1);

    temp->append(s2);
    return temp;

}

int main()

{

    string s1,s2;
    string heapOPRef;
    string *heapOPVal;
    cout<<"String Conact Experimentations\n";
    cout<<"Enter s-1 : ";
    cin>>s1;
    cout<<"Enter s-2 : ";

    cin>>s2;

    heapOPRef = concat_HeapRef(s1,s2);
    heapOPVal = concat_HeapVal(s1,s2);

    cout<<heapOPRef<<"  "<<heapOPVal<<" "<<endl;
        return -9;
}
4

3 回答 3

2

您的两个函数都是合法且正常的,除此之外,您稍后会从这两个函数中泄漏免费存储对象。

第一个函数返回对自由存储中值的引用,该值被复制到 main 中的局部变量中。第二个函数返回一个指向空闲存储中实例的指针,该指针存储在 main 中的指针变量中。

您的问题在于您不打印第二个字符串,而是打印它的地址,这要归功于有一个 operator<< 将指针包含的地址打印为数字。

如果您打算访问第二个变量的内容,您应该在使用它时取消引用它。

于 2013-11-04T14:31:32.487 回答
1

当您通过引用返回时,您表示(除其他外)调用者不会成为数据的所有者并且不负责释放它。

您已经分配了新块,并且对它的唯一剩余引用是您返回的那个。所以不能作为参考。

但它不适用于所有堆分配的块。如果你有一个堆分配的块,你在成员变量中持有指针以便稍后在析构函数中释放,你可能并且经常会通过引用返回它。


但实际上,指针std::string是一种代码味道。std::string应该大部分时间应该按值返回。也就是说,string,string *是按指针,而不是按值。

于 2013-11-04T09:13:10.400 回答
0

所以留给操作系统清理内存。对?

对。

你泄露了内存。

当您的进程结束时,您的操作系统将不得不自行回收内存,否则它将保持分配状态直到断电。

请不要这样做。

立即停止使用new:只需创建一个友好的新std::string对象并返回它。让编译器的优化和/或移动语义对所有内容进行排序。

于 2013-11-04T13:59:51.883 回答