将其放在堆栈中或放在堆中
leave it on stack or put in on heap?
碰巧函数使用本地缓冲区准备一些有限大小的数据块并将其传递给另一个函数,就像这样:
void foo()
{
char buffer[MAX_SIZE];
size_t size = write_fancy_things(buffer);
bar(buffer, size);
}
然而,根据MAX_SIZE
的值,您可能会担心占用太多的堆栈,并将代码替换为类似于以下示例的代码(但希望更关心内存管理):
void foo()
{
static char *buffer = new char[MAX_SIZE];
size_t size = write_fancy_things(buffer);
bar(buffer, size);
}
一般情况下,这两个函数的行为应该相同。然而,在第一个例子中,如果MAX_SIZE
太大,我们更有可能达到堆栈限制。如果您知道函数在哪里使用,那么使用较大的值可能是可以的,但有时您并不知道。
在第二个例子中,我们处理额外的间接和缓冲区更容易出现CPU缓存丢失,这可能是foo
位于低延迟关键路径上的情况,并且我们期望在大多数情况下准备缓冲区的成本非常低。
你认为什么尺寸的文件太大而不能放到堆栈中?另外,如果将大数据块放在堆栈上,但只使用其中的一小部分,会有什么损失吗?
EDIT: write_fancy _things
只是说*我正在向缓冲区写入一些数据,在1和MAX_SIZE字节之间*的同义词。您可以将第二个foo
示例视为类方法,将静态指针视为在构造函数中分配的类成员。我可能只是过分简化了一些东西,但我不想引入比需要更多的复杂性,并专注于堆栈问题。
两者根本不一样。第二个对所有调用使用相同的缓冲区,第一个使用一个新的缓冲区,这意味着第二个不是线程安全的。
风格太可怕了。如果write_fancy_things只使用X个字节,并且X在编译时是未知的,那么动态分配X个字节。不要在堆栈上分配一些有希望的最大大小,也不要使用更大的有希望的最大大小的静态缓冲区。使用正确类型的向量,将其大小调整为合适的大小,然后使用该缓冲区
将数据放在堆栈上没有任何损失,因为您只是在减少堆栈指针。
堆栈大小可以使用操作系统实用程序修改,所以我不会担心大到1MB的大小。
但是我担心递归调用。它们可能根本不会发生,因为它们会炸毁堆栈。
如果你开始担心大小,那就堆,否则堆栈。
如果出现帧边界冲突的问题(因为MAX_SIZE太大),则转换为std::vector
void foo()
{
std::vector<char> buffer(MAX_SIZE);
size_t size = write_fancy_things(&buffer[0]);
bar(&buffer[0], size);
}
坦率地说,你的版本是行不通的。
- 算法问题:查找从堆栈中弹出的所有序列
- 使用模板进行堆栈实现; "name followed by :: must be a class or namespace"
- Visual Studio(或任何其他工具)能否将地址解释为调用堆栈(boost上下文)的开头
- 为什么调用堆栈数组会导致内存泄漏
- gdb错误:Backtrace已停止:上一帧与此帧相同(堆栈已损坏?)
- 在 leetcode 上提交解决方案时出现堆栈缓冲区溢出错误
- 我的 int main() 中出现堆栈溢出错误
- 堆栈和队列是否像C++中的数组一样传递?
- 拥有映射的现代方法,该映射可以指向或引用已在堆栈上分配的不同类型的数据
- 为什么 STL 容器适配器堆栈中的 top 返回常量引用?
- 从堆栈分配的原始指针构造智能指针
- 在函数范围内在堆栈上分配的数组在离开函数时是否总是被释放?
- 堆栈中大小变量输入错误 (C++)
- 堆栈问题(平衡表达式问题集)
- C++ 在堆栈中包含多态属性的类对象存储
- 用于解析 win64 堆栈跟踪的命令行客户端(可以访问符号服务器)
- 在 C++ 中使用链表进行堆栈
- 变量周围的堆栈'...'已损坏
- 在 gtest 中初始化堆栈上的引用变量的隔离错误
- C++线程的可用堆栈大小