为什么我不能写以下内容?
char acBuf[nSize];
只是为了防止堆栈过度生长? 或者是否有可能做类似的事情,如果我可以确保我总是只需要几百千字节?
据我所知,std::string
使用其成员的内存来存储指定的字符串,只要它们不超过15个字符。只有当字符串更长时,它才会使用这个内存来存储一些堆分配内存的地址,然后获取数据。
在编译时,似乎必须100%确定堆栈在运行时是否对齐。真的吗?那是为什么?
答案 0 :(得分:1)
与C不同,C ++不支持可变长度数组。如果需要,可以使用非标准扩展,例如alloca
或GNU扩展(由clang和GCC支持)。他们有自己的注意事项,因此请务必阅读手册以确保安全使用它们。
堆栈布局主要是静态确定的原因是生成的代码必须执行较少的计算(添加,乘法和指针解除引用)以确定数据在堆栈中的位置。可以将偏移量硬编码到生成的机器代码中。
答案 1 :(得分:1)
它与阻止堆栈溢出无关,你可以使用class Saver():
def __init__(self):
self.d = {}
def state(self, name):
if not name in self.d:
return tf.zeros([1,LSTM_SIZE],tf.float32)
return self.d[name]
def save_state(self, name, val):
self.d[name] = val
return tf.identity('save_state_name') #<-important for control_dependencies
outputs, states = rnn.state_saving_rnn(stacked_lstm, inx, Saver(),
('lstmstate', 'lstmstate2', 'lstmstate3', 'lstmstate4'),sequence_length=[EVAL_SEQ_LEN])
#4 states are for two layers of lstm each has hidden and CEC variables to restore
network = [tf.matmul(outputs[-1], W) for i in xrange(EVAL_SEQ_LEN)]
完全溢出堆栈。在C ++中,必须在编译时知道数组大小,这是计算包含数组的结构大小所需的其他内容。
答案 2 :(得分:1)
为什么我不能写以下内容?
char a[SOME_LARGE_CONSTANT]
这些被称为可变长度数组(VLA&#39; s),并且不受C ++支持。原因是堆栈非常快,但与免费商店(你的话中的堆)相比很小。这意味着在任何时候你向VLA添加了很多元素,你的堆栈可能只是溢出而你得到一个模糊的运行时异常。这也可能发生在编译时大小的堆栈数组中,但这些更容易捕获,因为程序的行为不会影响它们的大小。这意味着在创建堆栈溢出之后,x不会发生,它就在那里。 This更详细地介绍了它。愤怒。
像char acBuf[nSize];
这样的容器使用更大的免费商店,并且有办法处理过度分配(抛出std::vector
)。
答案 3 :(得分:0)
我的建议是看看alloca.h
void *alloca(size_t size);
alloca()函数在堆栈中分配空间的大小字节 呼叫者的框架。此临时空间将自动释放 当调用alloca()的函数返回其调用者时。
答案 4 :(得分:0)
我在C ++中看到的一个可能的问题是类型。
acBuf
中char acBuf[nSize]
的类型是什么类型,char acBuf[nSize][nSize]
中更差?
template <typename T> void foo(const T&);
void foo(int n)
{
char mat[n][n];
foo(mat);
}
您无法通过引用传递该数组
template <typename T, std::size_t N>
void foo_on_array(const T (&a)[N]);
答案 5 :(得分:0)
你应该感到高兴的是,C ++标准不鼓励危险的做法(堆栈上的可变长度数组),而是鼓励一种不太危险的做法(可变长度数组和带堆分配的std :: vector)。
堆栈上的可变长度数组更危险,因为:
答案 6 :(得分:0)
为什么我不能写以下内容?
char acBuf[nSize];
你不能这样做,因为在C ++中,必须在编译时知道数组的长度,这是因为编译器为数组保留了指定的内存,并且在运行时不能修改它。它不是要防止堆栈溢出,而是关于内存布局。
如果要创建动态数组,则应使用new
运算符,以便将其存储在堆中。
char *acBuf = new char[nsize];