数组声明表示法是C语言中malloc的简写吗?

huangapple go评论62阅读模式
英文:

Is array declaration notation a shorthand for malloc in C?

问题

从这个教程网站中:

在C中声明数组,程序员通过以下方式指定数组的类型和所需的元素数量:

类型 数组名[数组大小];

这个语法似乎声明了数组并在内存中分配了空间,但没有初始化任何值。

这似乎类似于malloc命令。上述符号是malloc的缩写吗?

英文:

From this tutorial website:

> To declare an array in C, a programmer specifies the type of the
> elements and the number of elements required by an array as follows −
>
> type arrayName [ arraySize ];

It seems this syntax declares the array and gives it space in memory, but it doesn't initialise any of the values.

This seems similar to the malloc command. Is the above notation a shorthand for malloc?

答案1

得分: 3

这似乎类似于malloc命令。上面的表示法是malloc的简写吗?

不,不是。

根据存储持续时间,未初始化的对象将会是:

  1. 静态存储期 的对象会被清零。
  2. 自动存储期 的对象如果未初始化,则不会被初始化。

自动存储期的对象在退出定义它们的作用域时停止存在。

使用malloc分配的对象具有*分配存储期*,它们的生命周期与程序相同(除非您使用free释放它们)。

根据C标准:

具有外部或内部链接标识符声明的对象,或者带有static存储类说明符的对象,具有静态存储期。它的生命周期为整个程序的执行时间,其存储值只初始化一次,在程序启动之前。

具有无链接和没有static存储类说明符的标识符声明的对象具有自动存储期。

对于这样的对象(没有可变长度数组类型),其生命周期从进入与其关联的块开始,直到以任何方式结束该块的执行。(进入封闭块或调用函数会暂停但不会结束当前块的执行。)如果递归进入该块,则每次都会创建该对象的新实例。对象的初始值是不确定的。如果为对象指定了初始化,它将在执行块的声明达到时每次执行;否则,每次声明达到时该值都会变得不确定。

对于具有可变长度数组类型的对象,其生命周期从对象的声明开始,直到程序的执行离开该声明的范围。如果递归进入该范围,则每次都会创建该对象的新实例。对象的初始值是不确定的。

英文:

> This seems similar to the malloc command. Is the above notation a
> shorthand for malloc?

No, it is not.

Depending on the storage duration not initialized objects will be:

  1. zeroed having static storage duration
  2. not initialized if they have automatic storage duration
type array_static_storage_duration [ arraySize ];

void foo(void)
{
     type array_automatic_storage_duration [ arraySize ];
     static type array_static_storage_duration1 [ arraySize ];
    
}

Automatic storage duration objects will stop existing when you exit the scope you have defined them.

Objects allocated using malloc have allocated storage duration and their lifetime is the same as the program (unless you free them)

From C standard:

> An object whose identifier is declared with external or internal
> linkage, or with the storage-class specifier static has static storage
> duration. Its lifetime is the entire execution of the program and its
> stored value is initialized only once, prior to program startup.

> An object whose identifier is declared with no linkage and without the
> storage-class specifier static has automatic storage duration.
>
> 5 For
> such an object that does not have a variable length array type, its
> lifetime extends from entry into the block with which it is associated
> until execution of that block ends in any way. (Entering an enclosed
> block or calling a function suspends, but does not end, execution of
> the current block.) If the block is entered recursively, a new
> instance of the object is created each time. The initial value of the
> object is indeterminate. If an initialization is specified for the
> object, it is performed each time the declaration is reached in the
> execution of the block; otherwise, the value becomes indeterminate
> each time the declaration is reached.
>
> 6 For such an object that does
> have a variable length array type, its lifetime extends from the
> declaration of the object until execution of the program leaves the
> scope of the declaration.27) If the scope is entered recursively, a
> new instance of the object is created each time. The initial value of
> the object is indeterminate.

答案2

得分: 3

这里相关的是C语言中的_storage duration_概念,它主要告诉我们一个变量被保证保持有效的时间有多长,还有变量如何默认初始化以及在哪些条件下它们保持一个_不确定的值_(本质上是“垃圾值”)。

  • 具有_static storage duration_的对象保证被初始化为零。所有声明在任何函数外部和/或带有static关键字的对象都具有静态存储期。所以,如果你例子中的数组是在任何函数外部声明的,它_保证_被初始化为零。

  • 具有_automatic storage duration_的对象_不_会被初始化,除非程序员明确地这样做。这些对象都是在本地范围内声明的变量,我们称之为本地变量。但是函数的参数也属于这一类。如果你例子中的数组是在一个函数内部声明的,那么它具有自动存储期,它包含的值是不确定的。

  • 具有_allocated storage duration_的对象是由malloc系列函数明确创建的对象。它们是否被初始化取决于使用了哪个函数:malloc不会初始化这些值,而是将它们保持为不确定值,而calloc则会将所有的值初始化为零。

所以,恰好的是,具有自动存储期的变量和由malloc返回的具有分配存储期的数据具有相同的初始化规则。但是这两种变量类型在C语言中没有其他共同之处。

C语言并不规定内存中的存储位置。但是在实践中,C语言中的堆分配可能只会在函数明确表示时发生。除了malloc系列函数之外,还有一些非标准的函数,比如strdupgetline,它们明确说明它们在内部使用堆分配。

话虽如此,例如stdio.h的一些实现可能在内部使用堆分配——就C标准而言是可以的。如果它们没有进行文档说明,它们也会在内部进行free()清理。

英文:

What's relevant here is the C concept of storage duration, which mainly tells how long a variable is guaranteed to remain valid, but also if/how a variable is default-initialized and under which conditions it holds an indeterminate value (essentially "garbage value").

  • Objects with static storage duration are guaranteed to be zero-initialized. All objects declared outside any function and/or as static have static storage duration. So in case the array in your example is declared outside any function, it is guaranteed to be zero-initialized.

  • Objects with automatic storage duration are not initialized unless the programmer did so explicitly. These are all variables declared at local scope, what we refer to as local variables. But also parameters to functions. In case the array in your example is declared inside a function, then it has automatic storage duration and the values it contain are indeterminate.

  • Objects with allocated storage duration are those explicitly created by the malloc family of functions. If they are initialized or not depends on which function that was used: malloc does not initialize the values but leave them indeterminate, calloc does initialize all values to zero.

So just as it happens, a variable with automatic storage duration has the same initialization rules as data with allocated storage duration returned from malloc. But that's about all those two variable types have in common.

The C language does not dictate where in memory something is stored. However in practice, heap allocation in C can probably be assumed to only happen when a function explicitly says it will. Apart from malloc family, there are also some non-standard ones like strdup and getline which explicitly document that they use heap allocation internally.

That being said, some implementations of for example stdio.h may use heap allocation internally - which is fine as far as the C standard cares. If they don't document it, they will also do the clean-up free() internally.

答案3

得分: 1

不,函数malloc在运行时从自由存储区(或堆)分配内存。这块内存可以像数组一样访问,但被分配给一个指针。这种动态分配的“数组”通常在我们事先不知道它需要多大时使用。这块内存还需要使用函数free来释放。

英文:

No, the function malloc allocates memory at runtime from the free store (or heap). This memory can be accessed like an array but it is assigned to a pointer. This dynamically allocated "array" is typically used when we don't know in advance how large it needs to be. The memory also needs to be freed with the function free.

答案4

得分: 1

上述符号是否是malloc的缩写?

不是。当你将数组声明为

T a[N];

在内存中的表示看起来像这样:

   +---+
a: |   | a[0]
   +---+ 
   |   | a[1]
   +---+ 
   |   | a[2]
   +---+
    ...

除了数组元素本身之外,没有对象a。如果在函数内部声明,例如

void foo(void)
{
  T a[N];
  ...
}

数组的内存(通常)将来自与其他局部变量相同的存储区。当函数退出时,该内存也将被释放。

当你分配内存如下:

T *a = malloc(sizeof *a * N);

在内存中的表示看起来像这样:

   +---+         +---+
a: |   | ------> |   | a[0]
   +---+         +---+
                 |   | a[1]
                 +---+
                 |   | a[2]
                 +---+
                  ...

指针变量 a 被分配,就像任何普通变量一样,并且一旦函数退出,它就会被销毁,但是为数组元素分配的内存不会被销毁 - 该内存将一直分配,直到你显式调用free函数,所以你要么需要将指针返回给调用函数,要么在退出当前函数之前释放内存。

英文:

> Is the above notation a shorthand for malloc?

No. When you declare an array as

T a[N];

what you get in memory looks something like this:

   +---+
a: |   | a[0]
   +---+ 
   |   | a[1]
   +---+ 
   |   | a[2]
   +---+
    ...

There is no object a apart from the array elements themselves. If declared locally to a function, like

void foo( void )
{
  T a[N];
  ...
}

the memory for the array will (usually) be taken from the same store as any other local variable. That memory will also be released when the function exits.

When you allocate memory as

T *a = malloc( sizeof *a * N );

what you get in memory looks like this:

   +---+         +---+
a: |   | ------> |   | a[0]
   +---+         +---+
                 |   | a[1]
                 +---+
                 |   | a[2]
                 +---+
                  ...

The pointer variable a is allocated like any normal variable, and once the function exits it is destroyed, but the memory allocated for the array elements is not - that memory remains allocated until you explicitly call free, so you either need to return that pointer to any calling function or free the memory before you exit the current function.

huangapple
  • 本文由 发表于 2023年3月9日 18:25:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/75683296.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定