堆栈数组变量清理

Stack array variable cleanup

本文关键字:变量 数组 堆栈      更新时间:2023-10-16

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

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
}

根据我的理解,当函数退出时,堆栈变量会自动"删除",但我似乎无法理解为什么 read_file(( 函数中的 buf 变量在连续调用 evauluate(( 时没有被清除。

例如,如果我这样做;

int main(){
   evaluate(); // first call works as expected 
   evaluate(); // second call buf variable still has contents from previous call
   return 0;
}

我希望能提示解决这个问题的正确方向。提前谢谢。

无论它的价值如何,都没有必要清理释放的内存。一旦它被释放并重新获取,其内容的状态就会变成"不确定"。换句话说,它可能包含上次运行的数据,但绝对没有必要。你不能依赖这个。

如果您感到困惑,建议您对缓冲区进行零初始化:

char buf[SIZE] = {};

你可以看看这个问题。

这是未定义的行为。C++没有"堆栈"的概念,即特定于平台的细节。通常,当您释放"堆栈空间"时发生的情况是堆栈指针(即 x86 上的 esp .,堆栈向下增长(只是递增。但是,这并不意味着堆栈上的内容会自动消失。你不能依赖未定义的行为,因为标准没有说明会发生什么,所以任何事情都是"有效"的结果。

我似乎无法理解为什么read_file()函数中的buf变量在连续调用evaluate()时没有被清除。

强制始终清除内存,无论是在分配还是释放时,都可能会产生性能开销。但是,在初始化或释放内存时(即:在控制流离开声明buf的封闭块之前(,您可以自由地执行此操作。


考虑到 N 次连续调用evaluate(),如以下代码所示:

int main(){
   evaluate(); // first call  
   evaluate(); // second call
   ...
   evaluate(); // N call
   return 0;
}

意味着清除该内存 N 次(想想开销(。

请注意,即使对上述evaluate()的所有调用都将在堆栈上使用相同的内存空间,但在初始化之前读取内存也会导致未定义的行为。这样,标准就不会对清除具有自动存储持续时间的数据施加任何要求。

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