C++ 关于右值';作用域和内存泄漏

C++ 关于右值';作用域和内存泄漏,c++,c,memory-management,rvalue,C++,C,Memory Management,Rvalue,如果您“永远”停留在同一个块中,右值会发生什么情况 假设我有以下代码: char buff[999]; time_t timer; while(true){ ... time(&timer); strcpy(buff, ctime(&timer)); ... } 在每次迭代中,一个右值char*将从ctime返回,但它将在迭代结束时处理,还是仅在块完成时处理 如果只是在块完成时,那么经过数百万次迭代后,内存中可能会充满完成的右值char*对吗 (我用c和c++标

如果您“永远”停留在同一个块中,右值会发生什么情况

假设我有以下代码:

char buff[999];
time_t timer;
while(true){
...
    time(&timer);
    strcpy(buff, ctime(&timer));
...
}
在每次迭代中,一个右值
char*
将从
ctime
返回,但它将在迭代结束时处理,还是仅在块完成时处理

如果只是在块完成时,那么经过数百万次迭代后,内存中可能会充满完成的右值
char*
对吗


(我用
c
c++
标记了它,因为我也想知道这两者之间是否有区别)

出于历史原因,c库中的函数返回不同的内存类:

  • 不需要释放的静态分配内存。该库通常在其代码中将其声明为静态数组,并在每次函数调用时重复使用相同的内存区域
    ctime
    localtime
    就是这样的例子。不要释放此内存。(可能值得一提的是,这些函数被认为已弃用,并且有点消亡,因为它们不适合多线程操作)
  • 调用方需要释放的动态分配内存。该内存由库函数动态分配,库函数使用
    malloc()
    分配该内存,将指针返回给您,并希望您在使用完该内存后
    free()
    strdup()
    就是这个表单的一个很好的例子
您只需知道您正在使用的特定库调用将返回哪个类,就可以知道您是否需要
释放()
该内存。有关相应的呼叫,请参阅手册页


ctime()
的情况下,循环中的迭代绝对不重要。由于库在每次迭代时返回非常相同的缓冲区地址,并将其写入堆栈帧中非常相同的位置,因此不存在内存泄漏。如果在循环中调用strdup(),则会造成内存泄漏。

由于历史原因,C库中的函数返回不同的内存类:

  • 不需要释放的静态分配内存。该库通常在其代码中将其声明为静态数组,并在每次函数调用时重复使用相同的内存区域
    ctime
    localtime
    就是这样的例子。不要释放此内存。(可能值得一提的是,这些函数被认为已弃用,并且有点消亡,因为它们不适合多线程操作)
  • 调用方需要释放的动态分配内存。该内存由库函数动态分配,库函数使用
    malloc()
    分配该内存,将指针返回给您,并希望您在使用完该内存后
    free()
    strdup()
    就是这个表单的一个很好的例子
您只需知道您正在使用的特定库调用将返回哪个类,就可以知道您是否需要
释放()
该内存。有关相应的呼叫,请参阅手册页

ctime()
的情况下,循环中的迭代绝对不重要。由于库在每次迭代时返回非常相同的缓冲区地址,并将其写入堆栈帧中非常相同的位置,因此不存在内存泄漏。如果你在你的循环中调用了“代码> StrudUp”<代码>,你会创建内存泄漏。

(我这里说的是C,C++更复杂)

局部变量,例如

char buff[999];
time_t timer;
…通常在输入函数时一起分配。这些变量要么在堆栈帧中分配空间(在buff的情况下),要么直接在硬件寄存器上分配空间(在定时器的情况下可能)

所有这些分配在一条机器指令中一起完成,只需将指针移到堆栈顶部即可。每个函数调用只有一个局部变量实例,因此不会有内存被填满的危险,因为您在循环中使用它们。此外,这一内存区域的增长(大约10兆字节)将有一个相对较低的全局限制

当函数通过销毁堆栈帧退出时,所有局部变量都会自动处理。同样,只需再次将堆栈指针移回即可完成此操作。这与静态函数变量(它们只是具有有限可达性的全局变量)和动态分配(堆)变量(必须显式分配或释放)形成对比

堆栈框架有点太复杂,无法在这里完整介绍,但我建议您仔细阅读它们,因为了解函数调用的工作原理确实有助于全面理解C编程

如果你有关于变量存储的更具体的问题,我确信你可以在这里找到关于栈溢出的帮助,因为我们大多数的C程序员喜欢谈论这种事情:

(我这里谈论的是C,对于C++来说,这更复杂)

局部变量,例如

char buff[999];
time_t timer;
…通常在输入函数时一起分配。这些变量要么在堆栈帧中分配空间(在buff的情况下),要么直接在硬件寄存器上分配空间(在定时器的情况下可能)

所有这些分配在一条机器指令中一起完成,只需将指针移到堆栈顶部即可。每个函数调用只有一个局部变量实例,因此不会有内存被填满的危险,因为您在循环中使用它们。此外,这一内存区域的增长(大约10兆字节)将有一个相对较低的全局限制

所有本地