c++ - _alloca 和 std::vector 的 const char*
问题描述
我对 _alloca 函数进行了多次搜索,一般不推荐。我将有一个动态更新的字符串数组,我必须经常对其进行迭代。我希望在堆栈上分配每个字符串以尽可能减少未命中缓存。
使用 _alloca 我可以在堆栈上创建一个 char* 并将其放入向量中。我的 char 将位于一个不会影响我的堆栈的向量中,并且我知道当我在堆栈上分配字符串时,这些字符串永远不会大到导致堆栈溢出。
在这种情况下使用它是一件坏事吗?
该程序是否按照我的意愿执行?
#include <vector>
#include <cstring>
#ifdef __GNUC__
# define _alloca(size) __builtin_alloca (size)
#endif /* GCC. */
std::vector<const char*> vec;
void add(const char* message, int size) {
char* c = (char*) _alloca (size * sizeof(char*));
std::memcpy(c, message, sizeof(message));
vec.push_back(c);
}
int main() {
const char* c = "OK";
for (int i = 0; i < 10; ++i) {
add(c, 2);
}
}
解决方案
_alloca
当调用的函数_alloca
返回时,分配的堆栈内存会自动释放。指向它的指针被推到某个地方(特别是某个向量)这一事实并不能阻止该内存被释放(正如您在评论中提到的那样,您假设会发生),这不是 C++ 的工作方式。C++ 中没有“垃圾收集”。
因此,所示代码最终存储了一个指向已释放堆栈内存的指针。一旦add()
返回,这会留下一个悬空指针,任何后续使用它都会导致未定义的行为。
换句话说:是的,“在这种情况下使用它是一件坏事”,因为显示的代码将不起作用。
这个特定的电话还有其他几个主要的问题_alloca
,但这不是重点。即使这些问题得到正确解决,整个方法也会失败。
推荐阅读
- ssh - SSH 密码短语对话框在取消时会掉落到终端密码短语条目
- html - Boostrap 4 合并列与交替行
- c++ - 如何将文件存储在可执行文件中
- azure - 通过 VPN 使用 AS2 连接器的 Azure 逻辑应用
- c# - 如何在不和谐的 C# 中初始化公会?
- c# - OData、ASP.NET Core 3.1 WebApi、System.Text.Json 不工作
- c++ - 最长连续子数组的长度,使得子数组的 LCM 等于其中元素的乘积
- c# - HttpCookie - 无法更新现有的 cookie ASP.NET [Google Chrome]
- python - 为什么我收到 IndexError:数组索引过多
- mysql - 从重复记录中显示