按值和堆栈大小限制返回对象
Returning object by value and stacksize limit
据我了解,在现代C++中,建议按堆栈上的值返回对象,而不是在堆上分配内存,例如make_unique<>()
并返回unique_ptr
。编译器将确保不会复制返回的对象值。因此,建议信任编译器来优化按值返回的返回详细信息。
但是,如果我们要遵循此建议,即使对于大型对象,理论上也可能发生堆栈溢出,对吗?我在我的 Linux 笔记本电脑上对此进行了测试:
#include <iostream>
// Allocate 40 MB (10,000,000 x 4)
#define ASIZE 10000000
struct Foo {
int a[ASIZE]; // Note: On my Linux laptop, sizeof(int) == 4
};
Foo get_foo() {
Foo a_foo;
a_foo.a[1] = 2;
return a_foo;
}
int main() {
Foo myfoo = get_foo();
std::cout << "sizeof(a) = " << sizeof(struct Foo) << "n";
std::cout << "foo1 = " << myfoo.a[1] << "n";
return 0;
}
如果ASIZE
== 10,000,000,则此程序因分段错误而中止,但如果ASIZE
== 1,000,000。
(我希望有一个更具描述性的错误消息,如Stackoverflow! Abort
或:)的东西(。 无论如何,这与在堆栈上返回值的建议有何关系?它是否仅适用于对象的大小较小的情况?还是我错过了什么?
您始终可以从基于堆栈的容器开始,但对于堆栈上的数组,您更喜欢 std::array 或 stack_array,以避免将数组视为指针的陷阱。通常,保存所有数据的单个数组可能意味着存在数据设计问题,因此在切换到堆对象之前,我会先考虑一下,而无需三思而后行。
如果堆栈大小确实是问题所在,则可以使用基于堆的标准库容器(例如vector
、list
等(。这些解决了堆栈溢出问题并支持移动语义,因此使用引用和按值复制仍然应该优先于使用智能指针。
相关文章:
- 如何返回对象C++的数组
- 如何使用std::min和std::less返回对象
- 如何通过引用返回对象
- 如何安全地从 DLL 调用返回对象
- 如何在不销毁对象的情况下返回对象列表
- 什么更好?返回对象指针列表?或返回指向对象列表的指针?
- 使用返回对象的函数处理错误
- 何时返回指针与返回对象的一般经验法则?
- 如何使用运算符+重载函数正确返回对象?
- C++,class,一个返回对象的函数
- 运算符的返回对象 = C++ 中的重载
- 从队列返回对象的最快方法,但前提是队列有它
- 如何使用条件表达式返回对象指针?
- 使用构造函数从函数返回对象
- 隐式转换函数的返回对象时是否会影响性能?
- 返回对象时从'const DList<int>* const'到 'DList<int>*' [-fallowive] 的转换无效
- 按值和堆栈大小限制返回对象
- 我应该如何从函数返回对象?
- c++:何时传递指针与返回对象
- 返回对象会丢失属性