堆栈数组变量清理

时间:2018-01-10 11:46:41

标签: c++

我正在使用以下函数从文件中读取。

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;
}

我很欣赏在解决这个方面给出正确方向的暗示。提前谢谢。

4 个答案:

答案 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)

首先,你班上有设计问题。 堆栈变量仅在它们声明的函数中有效。 因为堆栈指针可能有效,所以它们不能用于检查。 每次阅读时都使用分配的缓冲区(newmalloc()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;中会出现下一个问题。应该考虑复制数组的其他方法。