在C中处理本地定义的变量



假设我们有以下代码:

void foo() {
  char buffer[100];
}

在C中有一种(最好是便携式(方式来换取 buffer 从运行时堆栈(类似((返回?

no。您可以在C中做的最好的方法是使用范围:

void foo()
{
    {
        char buffer[100];
    }
}

并依靠编译器来考虑内部范围退出后再次使用buffer的100个字节。不幸的是,标准不能保证这一点,您需要依靠编译器。例如,在典型的Linux机器上考虑以下程序,其堆栈空间为8192KB(ulimit -s(:

#include <stdio.h>
int main(void)
{
    {
        char buffer1[8192 * 800] = { 0 };
        ((char volatile *)buffer1)[0] = buffer1[0];
        printf("%pn", buffer1);
    }
    {
        char buffer2[8192 * 800] = { 0 };
        ((char volatile *)buffer2)[0] = buffer2[0];
        printf("%pn", buffer2);
    }
    return 0;
}

(怪异的铸件是防止缓冲变量被优化。(

当不使用优化构建时,该程序将溢出某些编译器上的可用堆栈空间。例如,clang -O0将崩溃,但是clang -O1将重复使用buffer2buffer1内存,并且两个地址都相同。换句话说,当示波器退出时,buffer1已被"释放"。

gcc也将在-O0处进行此优化。

给定:

void foo(void) {
  char buffer[100];
}

对象buffer lifetime 在执行到达开放 {(输入函数时(并在执行离开块时结束,到达闭合}(或以其他方式,例如以其他方式(gotobreakreturn语句(。

除离开块外,没有办法结束buffer的寿命。如果您想对其进行处理,则必须以其他方式分配它。例如,如果您通过调用malloc()分配对象,则可以(几乎必须(通过调用free

来对其进行处理。
void foo(void) {
    char *buffer_ptr = malloc(100);
    if (buffer_ptr == NULL) /* error handling code here */
    /* ... */
    if (we_no_longer_need_the_buffer) {
        free(buffer_ptr);
    }
    /* now buffer_ptr is a dangling pointer */
}

一种替代方法是通过在嵌套块中定义buffer的寿命:

void foo(void) {
    /* ... */
    {
        char buffer[100];
        /* ... */
    }
    /* buffer's lifetime has ended */
}

,但仅仅是因为buffer的寿命在控制离开内部块时结束,这并不能保证它在物理上被划分。在抽象计算机中,buffer离开内部块后不再存在,但是生成的代码可能仅仅因为它更方便而将其留在堆栈上。

如果要控制分配和交易,则需要使用mallocfree

因为 char buffer[100];被声明为 void foo()的函数堆栈本地,当 void foo()返回时, buffer的存储空间被发布以进行重复使用,并且在此之后不再有效。

因此,您无需执行或可以做任何事情来" DealLocate buffer ",因为buffer自动处理的是具有自动存储时间例如请参阅:C11标准-6.2.4对象的存储持续时间(P5(

它是自动变量,您不必做任何事情,因为离开范围时它将重新分配。在您的情况下,当您从功能返回

如果要使范围缩小范围,只需将其放置在另一个范围内即可。

foo()
{
      for(... .)
      {
              // if defined here it will be only in the for loop  scope
       }
       {
           // if defined here it will be only in this internal scope
        }
}

裸露的是它需要允许它的C标准。

相关内容

  • 没有找到相关文章

最新更新