wog*_*gio 3 c++ memory-management
我已经使用 C++ 一段时间了,但至少还有一件事我无法理解,我也无法在网上冲浪找到很好的解释。它与内存管理有关,可以用这个例子来说明:
考虑 std::string 的字符串连接运算符,它看起来像这样
std::string operator+(const string&s1, string&s2)
众所周知,它返回一个新创建的对象(另一个 std::string),其中包含连接的两个原始字符串。我的问题是:这怎么可能?这个对象在内存中的什么地方?
我的意思是,如果我必须编写函数实现,我会做这样的事情
std::string std::string::operator+(const string& s1, string& s2)
{
std::string *res=new std::string;
// fill res with the content of s1 and s2
return *res;
}
Run Code Online (Sandbox Code Playgroud)
但是通过这种方式我知道我会导致内存泄漏,因为如果我调用该函数一百万次,我将生成一百万个字符串,这些字符串在程序结束之前不会被释放。另一方面,我可以这样做:
std::string& std::string::operator+(const string& s1, string& s2)
{
std::string res;
// fill res with the content of s1 and s2
return res;
}
Run Code Online (Sandbox Code Playgroud)
但是通过这种方式,我会返回对局部变量的引用,一旦函数返回,该变量就会变成垃圾。最后我可以简单地写
std::string std::string::operator+(const string& s1, string& s2)
{
std::string res;
// fill res with the content of s1 and s2
return res;
}
Run Code Online (Sandbox Code Playgroud)
并按值传递结果,这应该可以完成任务,但在我看来效率很低,因为我必须将整个 res(理论上可能非常大)对象复制到调用函数。我这样说是因为我实际上正在研究一个线性代数库,并且只执行例如矩阵加法会非常好
m3=m1+m2;
Run Code Online (Sandbox Code Playgroud)
就像字符串连接一样,但如果唯一的解决方案是将结果对象复制回,那么使用双矩阵(例如 100MB)是不切实际的。目前我使用的功能是
matrix& matrix::sum(matrix& m1, matrix& m2)
Run Code Online (Sandbox Code Playgroud)
以这种方式使用
m3.sum(m2,m1);
Run Code Online (Sandbox Code Playgroud)
这看起来很难看,也阻止我在一行中总结多个矩阵,我必须写
m4.sum(m1,m2)
m4.sum(m4,m3)
Run Code Online (Sandbox Code Playgroud)
或者
(m4.sum(m1,m2)).(m4,m3)
Run Code Online (Sandbox Code Playgroud)
如果我真的想把它写成一行,但它绝对不可读。
有没有更好的方法来做所有这些事情?
提前致谢
这个版本是对的
std::string std::string::operator+(const string& s1, string& s2)
{
std::string res;
// fill res with the content of s1 and s2
return res;
}
Run Code Online (Sandbox Code Playgroud)
大多数编译器采用一种称为命名返回值优化的优化技术来处理复制值的低效问题。标准明确允许这样做,称为复制省略。
在 C++11 中有另一种方法:当你返回 string 时res
,它变成了一个 r 值,并且移动构造函数将被用来代替复制构造函数,这也很便宜。但同样,大多数编译器都优化了复制和移动。
最后不知道为什么要自己实现一个矩阵库。如果它不是家庭作业,请改用 Eigen。优化矩阵代数是一项非常艰巨的工作,需要大量的底层理解。
归档时间: |
|
查看次数: |
1681 次 |
最近记录: |