C语言 内存何时分配给 C 中的局部变量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15385411/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 05:40:48  来源:igfitidea点击:

When is memory allocated to local variables in C

cvariablesmemory-managementlocal

提问by linuxD

As local variables are also called automatic variables, and are supposed to be allocated memory at run time, when function is accessed.

由于局部变量也称为自动变量,并且应该在运行时访问函数时分配内存。

int main(){
    int a; // declaration 
    return 0;
}

int main(){
    int a[]; // compilation error, array_size missing
    return 0;
}

int main(){
    int a[2]; // declaration, but can't work without array_size, 
              // so at compile time it is checked!
    return 0;
}

My question is whether it's just a rule to give array_size in declaration in C, or memory is allocated at compile time for array (still local variable)

我的问题是在 C 中的声明中给出 array_size 是否只是一个规则,或者在编译时为数组分配内存(仍然是局部变量)

How does it work?

它是如何工作的?

An array is a variable as per C programming by K&R. pg no 161.

根据 K&R 的 C 编程,数组是一个变量。第 161 页。

回答by Valeri Atamaniouk

When you declare local variable, the size of it is known at a compile time, but memory allocation occurs during execution time.

当你声明局部变量时,它的大小在编译时是已知的,但内存分配发生在执行时。

So in your examples, array without a size is clearly a problem to compiler, as it doesn't know what is the size to include into assembler code.

因此,在您的示例中,没有大小的数组显然是编译器的一个问题,因为它不知道要包含在汇编代码中的大小是多少。

If you don't know the size of an array, you can always use pointer types and malloc/freeor even alloca. The first two operate on heap, and allocaactually uses stack.

如果您不知道数组的大小,您始终可以使用指针类型和malloc/free或什至alloca. 前两个操作在堆上,alloca实际使用栈。

The notable exception is static variables. The storage for them is allocated at a compile/link time already and can't be changed at runtime.

值得注意的例外是静态变量。它们的存储已经在编译/链接时分配,不能在运行时更改。

Examples:

例子:

int main(int argc, const char *argv[])
{
    int a; // a is a sizeof(int) allocated on stack
}

int main(int argc, const char *argv[])
{
    int a[2]; // a is a sizeof(int)*2 allocated on stack
}

int main(int argc, const char *argv[])
{
    int *a; // a is a sizeof(int*) allocated on stack (pointer)
    a = alloca(sizeof(int)*4); // a points to an area with size of 4 integers
                               // data is allocated on stack
}

int main(int argc, const char *argv[])
{
    static int a; // a is allocated in data segment, keeps the value
}

回答by teppic

There's a difference between localand automaticvariables in C. A local variable may be automaticor static, which determines whether the memory for it is allocated on the stack, or permanently, when the program is first executed.

还有之间的差本地自动在C.局部变量的变量可以是自动的静态的,这决定了它的存储器是否被分配在堆栈上,或永久地,首先执行该程序时。

With this code:

使用此代码:

int main(){
  int a[];    //compilation error, array_size missing
  return 0;
}

This is an incomplete array. The error is because the compiler doesn't know how many ints the program will need to allocate.

这是一个不完整的数组。错误是因为编译器不知道int程序需要分配多少s。

回答by Steve Jessop

int main(){
    int a[2];
    return 0;
}

Here, int a[2];is a definitionof a variable named a. ais an array of two int.

这里,int a[2];是一个名为 的变量的定义aa是两个的数组int

What happens in practice is that the compiler emits code to use space on the stack for 2 adjacent intobjects (probably 8 bytes, but the size of intis up to the implementation). That's assuming of course that the object isn't removed by the optimizer because you never use it.

在实践中发生的情况是编译器发出代码以将堆栈上的空间用于 2 个相邻int对象(可能是 8 个字节,但大小int取决于实现)。当然,这是假设优化器不会删除该对象,因为您从未使用过它。

The compiler error you got for int a[999999999];is due to some hard limit enforced by the compiler, because it knows (or anyway assumes) there will never be enough stack for that.

您遇到的编译器错误int a[999999999];是由于编译器强制执行了一些硬限制,因为它知道(或无论如何假设)永远不会有足够的堆栈。

回答by μtex

Array size should be known at the compile time and you can pass size either directly to the array or indirectly as memory is decided at compile time but allocated at run time, except for the variable sized array.

应该在编译时知道数组大小,您可以将大小直接传递给数组,也可以间接传递给数组,因为内存是在编译时决定的,但在运行时分配,但可变大小的数组除外。

回答by Inisheer

As sgar91 stated in the comments, an array such as in your example is allocated when a function is called and must be determinate in size. If you need dynamic arrays, you must allocate the memory on the heap.

正如评论中的 sgar91 所述,在调用函数时会分配一个数组,例如您的示例中的数组,并且必须确定大小。如果需要动态数组,则必须在堆上分配内存。

int *values = malloc(sizeof(int) * array_count);

回答by Rajeshirke

Automatic allocation happens when you declare an automatic variable, such as a function argument or a local variable. The space for an automatic variable is allocated when the compound statement containing the declaration is entered, and is freed when that compound statement is exited.

当您声明一个自动变量时会发生自动分配,例如函数参数或局部变量。自动变量的空间在包含声明的复合语句进入时分配,并在复合语句退出时释放。

回答by flyingOwl

Thats the point in C, where arrays and pointers aren't the same.

这就是 C 中的重点,其中数组和指针是不一样的。

Take this example:

拿这个例子:

int main(){
   int a[5];
   int * b = malloc(sizeof(int) * 5);

  printf("sizeof a = %d\n",sizeof a);
  printf("sizeof int[5] = %d\n",sizeof(int[5]));
  printf("sizeof b = %d\n",sizeof b);

  free(b);
  return 0;
}

This will return:

这将返回:

sizeof a = 20
sizeof int[5] = 20
sizeof b = 4

The variable a is internal declared as int[5], an integer pointer pointing to a memory block with space for 5 integers.

变量 a 在内部声明为 int[5],这是一个整数指针,指向一个内存块,有 5 个整数的空间。

回答by wilsonmichaelpatrick

For local variables, the memory they consume is on the stack. This means that they must have a fixed size known at compile time, so that when the function is called, the exact amount of memory needed is added to the stack by changing the value of the stack pointer. This is why the array must have a size: the number of bytes on the stack must change by a fixed amount when the function is called.

对于局部变量,它们消耗的内存在堆栈上。这意味着它们必须具有在编译时已知的固定大小,以便在调用函数时,通过更改堆栈指针的值将所需的确切内存量添加到堆栈中。这就是数组必须具有大小的原因:调用函数时,堆栈上的字节数必须更改固定数量。

Calls to malloc() and similar allocate memory from the heap; memory allocated in this way at runtime can be of variable size.

调用 malloc() 和类似的从堆分配内存;在运行时以这种方式分配的内存可以是可变大小的。