_alloca 和 std::vector of const char*
_alloca and std::vector of const char*
我在_alloca 函数上搜索了几次,一般不推荐使用。
我将有一个动态更新的字符串数组,我将不得不经常对其进行迭代。
我想在堆栈上分配每个字符串以尽可能减少未命中缓存。
使用 _alloca 我可以在堆栈上创建一个 char* 并将其放入向量中。
我的 char 将在一个不会影响我的堆栈的向量中,而且我知道当我在堆栈上分配它们时,字符串永远不会大到足以产生 Whosebug。
在这种情况下使用它是不是一件坏事?
程序是否按照我的要求执行?
#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
returns 时,由 _alloca
分配的堆栈内存会自动释放。指向它的指针被推到某个地方(特别是某个向量)这一事实并不能阻止释放该内存(正如您在评论中提到的那样,您假设会发生),这不是 C++ 的工作方式。 C++中没有“垃圾回收”。
因此,所示代码最终存储了指向已释放堆栈内存的指针。一旦 add()
returns,就会留下悬空指针,任何后续使用都会导致未定义的行为。
换句话说:是的,“在这种情况下使用它是一件坏事”,因为显示的代码将不起作用。
这个特定的 _alloca
调用还有其他几个主要问题,但这不是重点。整个方法都失败了,即使这些问题得到正确修复。
我在_alloca 函数上搜索了几次,一般不推荐使用。 我将有一个动态更新的字符串数组,我将不得不经常对其进行迭代。 我想在堆栈上分配每个字符串以尽可能减少未命中缓存。
使用 _alloca 我可以在堆栈上创建一个 char* 并将其放入向量中。 我的 char 将在一个不会影响我的堆栈的向量中,而且我知道当我在堆栈上分配它们时,字符串永远不会大到足以产生 Whosebug。
在这种情况下使用它是不是一件坏事?
程序是否按照我的要求执行?
#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
returns 时,由 _alloca
分配的堆栈内存会自动释放。指向它的指针被推到某个地方(特别是某个向量)这一事实并不能阻止释放该内存(正如您在评论中提到的那样,您假设会发生),这不是 C++ 的工作方式。 C++中没有“垃圾回收”。
因此,所示代码最终存储了指向已释放堆栈内存的指针。一旦 add()
returns,就会留下悬空指针,任何后续使用都会导致未定义的行为。
换句话说:是的,“在这种情况下使用它是一件坏事”,因为显示的代码将不起作用。
这个特定的 _alloca
调用还有其他几个主要问题,但这不是重点。整个方法都失败了,即使这些问题得到正确修复。