这个数组是静态的还是动态的?

4
所以我正在学习内存分配,它说你只能使用malloc()动态分配内存;但这不也是动态内存分配吗?顺便说一下,它是有效的。所以我有点困惑。
#include<stdio.h>
#include<conio.h>
int main()
{
    int integer,cntr;
    scanf("%d",&integer);
    char words[integer];
    for(cntr = 0;cntr < integer - 1;cntr++)
        words[cntr] = 'k';
    words[cntr] = '\0';
    printf("%s",words);
    getch();
    return(0);
}
3个回答

4
那是一个可变长度数组。尽管大小确实是动态的,但在实践中,它通常会被分配到堆栈上而不是堆上(所以不要用它来处理太大的数据)。
根据您的编译器等因素,这可能比分配堆内存要快得多,因为它只是对堆栈指针的调整。
可变长度数组是在C99标准中引入的,因此请记住,您将无法在非常旧的C编译器(例如MSVC)中使用它们。

等等,我有点困惑,所以它是动态的?但是@jack/在下面评论/因为它被分配在堆栈中而不是堆中,所以它仍然被认为是静态的。我原以为动态的定义是如果内存将在运行时分配。 - jantristanmilan
好的,我的意思是大小是动态的,并在运行时确定。堆栈仍然是静态的内存块,在创建线程时分配有限的大小。 - James M
尽管大小是动态的且在运行时确定,只要它分配在堆栈而不是堆上,它仍然是静态的?以防它在考试中出现。 - jantristanmilan
2
通常最好将其视为“动态”(即手动分配)和“自动”。区别在于谁负责分配和释放。对于自动存储,编译器会处理它(通常不允许您干扰);对于动态存储,您必须自己使用mallocfree来管理内存。 - cHao
@cHao 但在测试中,什么是最好的答案?我不能问我的教授,因为第二学期还没有开始。 - jantristanmilan
1
@vincent:正确答案是“自动”。它不是动态的,因为您不必(实际上也不能)使用malloc,它也不是静态的,因为它在函数结束时被清除。 “静态”实际上意味着“存活到程序的最后”。 - cHao

1
该数组是一个本地数组,一旦它的定义范围({,})结束,它将自动释放。
从技术上讲,标准并未指定应在何处分配该数组,而仅定义了此类数组必须提供的特征。标准甚至没有提及堆栈或堆。

0

这是静态的,因为数组是在堆栈上分配而不是在堆上。

它不是由内存管理器分配的,只是在堆栈上保留,但没有更多的操作。一旦超出范围,它就会停止存在(在使用它提供垃圾的意义上)。

请注意,由于堆栈是有限的,您将无法以这种方式分配如此大的数组。


如果它在堆栈上,那么它就不是静态的。静态分配意味着地址在程序的整个运行期间都是固定的。你可以想象对激活记录进行静态分配——当然,在没有递归的情况下——这甚至在早期的FORTRAN编译器中也被实现了,但我认为没有人为C或C++做过这样的事情。 - AProgrammer
我同意使用静态关键字来定义栈分配的对象有些不妥。但是从正确的角度来看,它也不是动态的,因为它没有由任何内存分配器管理,只是在栈上保留。正如詹姆斯所解释的那样,它被认为是“自动”的。 - Jack

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接