Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 为什么使用固定长度分配而不是静态分配?_C_Arrays_Int_Malloc - Fatal编程技术网

C 为什么使用固定长度分配而不是静态分配?

C 为什么使用固定长度分配而不是静态分配?,c,arrays,int,malloc,C,Arrays,Int,Malloc,我知道我的问题对你们中的一些人来说可能很简单,但请耐心听我说,我试图理解内存管理。既然我们对尺寸使用了一定的固定长度(N),为什么我们还要这样做: int *arr = (int*)malloc(N * sizeof(int)) ..代替传统的静态方式: int arr[N]; malloc。这是动态分配。您可以释放或更改分配内存的大小。堆通常比堆栈或全局变量内存区域大得多。内存与静态对象具有相同的存储持续时间 后者无法调整大小或释放(通过退出作用域而自动释放的对象除外)。静态和自动存储通常

我知道我的问题对你们中的一些人来说可能很简单,但请耐心听我说,我试图理解内存管理。既然我们对尺寸使用了一定的固定长度(N),为什么我们还要这样做:

int *arr = (int*)malloc(N * sizeof(int))
..代替传统的静态方式:

int arr[N];

malloc
。这是动态分配。您可以释放或更改分配内存的大小。堆通常比堆栈或全局变量内存区域大得多。内存与静态对象具有相同的存储持续时间


后者无法调整大小或释放(通过退出作用域而自动释放的对象除外)。静态和自动存储通常比堆小。

malloc
提供在执行其所在的块结束后(例如当其所在的函数返回时)仍然可用的内存

int A[N]
,如果它出现在函数中,则使用保证仅在其所在块的执行未结束时可用的内存。如果它出现在函数外部,则内存可用于所有程序执行,但
N
必须为常数。(此外,即使在函数内部,
inta[N]
其中
N
不是常量,在某些C实现中也不受支持。)


在通用操作系统中的典型C实现中,
malloc
提供了大量可用内存,但函数内部的
int a[N]
使用了有限的堆栈区域,通常总共1到8兆字节,具体取决于系统。

int arr[N]在文件范围中(或前面有
static
),或者在堆栈上,它就会进入静态内存

静态存储器
intarr[N]
是最便宜的分配方式(就大小开销和分配时间而言),但它永远不会被释放,内存也不会总是缓存本地的

如果
int-arr[N]位于块内(前面没有
static
),
int arr[N]进入堆栈。这个内存几乎肯定是缓存本地的,但是如果
N
很大并且堆栈有限(或者有堆栈溢出的风险),或者
arr
的生存期需要超过其包含块的生存期,那么您可能不希望使用这个形式

malloc
'd内存分配需要一些时间(几十到几百纳秒),它可能会带来一些大小开销,分配可能会失败,但您可以
稍后释放
内存,直到您释放它为止。它也可以调整大小(通过
realloc
),而无需复制内存。就缓存位置而言,它有点像静态内存(即,块可能远离堆栈的缓存热端)

因此,这些是需要考虑的因素:生存期堆栈大小分配时间大小开销空闲能力,以及可能的缓存位置


最后一个考虑可能是C的一个特殊特性:有效类型。声明的数组具有固定的有效类型,因此在不违反C的严格别名规则的情况下无法重新键入,但是
malloc
'd内存可以被删除。换句话说,您可以使用
malloc
'd块作为您自己的通用分配器的后备存储,但严格来说,声明的
char
数组不能这样使用。

显然,第一个块是从堆中分配的。第二个通常从堆栈分配(可能是实现定义的,我不知道)。如果N为“大”,则首选第一种,否则选择第二种。堆栈空间通常比堆空间更为有限。扩展堆栈空间,它们的生存期可能会有所不同。第一个内存在显式释放之前一直存在。第二个,如果在函数中声明,则仅存在于函数中,并且在函数退出时消失。@500 InternalServerError静态存储持续时间不在堆栈上。如果使用malloc,看起来在某种程度上更干净。获得更多的控制来释放、遍历或操纵内存。谢谢你的回答!有道理!非常感谢你!写更改分配内存的大小有点混乱。。。内存块可以重新分配,新地址可以存储到指针中。我感谢您的详细回答!谢谢