我正在使用以下函数从文件中读取。
void read_file(){
char buf[BUF_SIZE];
// file is a vraiable defined and assigned during initialization
int numread = pread(file->fd, buf, BUF_SIZE, file->curpos);
// other logic follows
file->buffer += buf;
}
以下函数仍在同一个类中,用于计算从文件中读取的缓冲区的内容。
void evaluate(){
read_file();
//evaluate the file->buffer contents
}
根据我的理解,自动删除堆栈变量'当一个函数退出但我似乎无法理解为什么在连续调用evauluate()时没有清除read_file()函数中的buf变量。
例如,如果我这样做;
int main(){
evaluate(); // first call works as expected
evaluate(); // second call buf variable still has contents from previous call
return 0;
}
我很欣赏在解决这个方面给出正确方向的暗示。提前谢谢。
答案 0 :(得分:1)
无论它的价值如何,清除释放的内存都是不必要的。一旦它被释放并重新获得,其内容的状态就会变成“不确定”。换句话说,可能包含上次运行的数据,但绝对没有必要。你不能依赖这个。
如果您感到困惑,建议您对缓冲区进行零初始化:
char buf[SIZE] = {};
您可以查看this question。
答案 1 :(得分:1)
这是未定义的行为。 C ++没有“堆栈”的概念,这是一个特定于平台的细节。通常,当你释放“堆栈空间”时会发生的事情是堆栈指针(即x86上的esp
。,堆栈向下增长)只是递增。但是,这并不意味着堆栈上的东西会自动消失。您不能依赖未定义的行为,因为标准没有说明会发生什么,所以任何都是“有效”的结果。
答案 2 :(得分:1)
我似乎无法理解为什么
buf
函数中的read_file()
变量在连续调用evaluate()
时未被清除。
强制始终清除内存,无论是在分配还是释放时都会产生性能开销。但是,在初始化或释放时(即:在控制流离开声明buf
的封闭块之前),你可以自由地这样做。
考虑 N 对evaluate()
的连续调用,如下面的代码所示:
int main(){
evaluate(); // first call
evaluate(); // second call
...
evaluate(); // N call
return 0;
}
意味着清除内存 N 次(考虑开销)。
请注意,即使上面对evaluate()
的所有调用都在堆栈上使用相同的内存空间,在初始化之前读取内存会导致未定义的行为。通过这种方式,标准不会对清除自动存储持续时间的数据进行重新征服。
答案 3 :(得分:0)
首先,你班上有设计问题。
堆栈变量仅在它们声明的函数中有效。
因为堆栈指针可能有效,所以它们不能用于检查。
每次阅读时都使用分配的缓冲区(new
,malloc()
,HeapAlloc()
或其他功能
void evaluate(){
char *buf = new char[BUF_SIZE];
read_file(buf);
//evaluate the file->buffer contents
delete [] buf;
}
并且
void read_file(char *buf){
int numread = pread(file->fd, buf, BUF_SIZE, file->curpos);
// other logic follows
file->buffer += buf;
}
这可以帮助您解决问题,但file->buffer += buf;
中会出现下一个问题。应该考虑复制数组的其他方法。