为什么使用固定长度分配而不是静态分配?
Why use fixed length allocation instead of static allocation?
我知道我要问的问题对你们中的一些人来说可能很简单,但请耐心等待,我正在努力了解内存管理。由于我们使用一定的固定长度(N)作为尺寸,为什么我们也这样做:
int *arr = (int*)malloc(N * sizeof(int))
..而不是传统的静态方式:
int arr[N];
malloc
。这就是动态分配。您可以释放或更改已分配内存的大小。堆通常比堆栈或全局变量内存区域大得多。内存与静态对象的存储时间相同
后者不能调整大小或释放(退出范围自动对象除外)。静态和自动存储通常比堆小。
malloc
提供在块执行结束后仍然可用的内存,例如当它在 returns.
中的函数时
int A[N]
,如果它出现在函数内部,则使用保证仅在其所在块的执行尚未结束时可用的内存。如果它出现在函数外部,则内存可用于所有程序执行,但 N
必须是常量。 (此外,即使在函数内部,某些 C 实现也不支持 int A[N]
,其中 N
不是常量。)
在通用操作系统的典型 C 实现中,malloc
可以提供大量可用内存,但是 int A[N]
函数内部使用有限的堆栈区域,通常是一个总共八兆字节,具体取决于系统。
如果 int arr[N];
在文件范围内(或前面有 static
)或在堆栈上,则
int arr[N];
进入静态内存。
静态内存 int arr[N];
的分配成本最低(在大小开销和分配时间方面),但它永远不会被释放,并且内存不会始终是缓存本地的。
如果 int arr[N];
在块内(并且前面没有 static
),则 int arr[N];
进入堆栈。这个内存几乎肯定是缓存本地的,但如果 N
很大并且你的堆栈有限(或者你有堆栈溢出的风险)或者如果 [=17 的生命周期,你可能不希望使用这种形式=] 需要超过它的包含块。
malloc
的内存需要一些时间来分配(几十到几百ns),它可能会带来一些大小开销,并且分配可能会失败,但是你可以稍后free
内存它会一直保留到您执行 free
为止。它也可以调整大小(通过 realloc
)而无需复制内存。缓存位置方面,它有点像静态内存(即,该块可能远离堆栈的缓存热端)。
所以这些是考虑因素:生命周期、堆栈大小、分配时间、大小开销、自由能力,可能还有缓存位置。
最后的考虑可能是 C 的一个特殊特性:有效类型。声明的数组具有固定的有效类型,因此不能在不违反 C 的严格别名规则的情况下重新键入,但 malloc
的内存可以。换句话说,您可以使用 malloc
块作为您自己的通用分配器的后备存储,但严格来说,声明的 char
数组不能以这种方式使用。
我知道我要问的问题对你们中的一些人来说可能很简单,但请耐心等待,我正在努力了解内存管理。由于我们使用一定的固定长度(N)作为尺寸,为什么我们也这样做:
int *arr = (int*)malloc(N * sizeof(int))
..而不是传统的静态方式:
int arr[N];
malloc
。这就是动态分配。您可以释放或更改已分配内存的大小。堆通常比堆栈或全局变量内存区域大得多。内存与静态对象的存储时间相同
后者不能调整大小或释放(退出范围自动对象除外)。静态和自动存储通常比堆小。
malloc
提供在块执行结束后仍然可用的内存,例如当它在 returns.
int A[N]
,如果它出现在函数内部,则使用保证仅在其所在块的执行尚未结束时可用的内存。如果它出现在函数外部,则内存可用于所有程序执行,但 N
必须是常量。 (此外,即使在函数内部,某些 C 实现也不支持 int A[N]
,其中 N
不是常量。)
在通用操作系统的典型 C 实现中,malloc
可以提供大量可用内存,但是 int A[N]
函数内部使用有限的堆栈区域,通常是一个总共八兆字节,具体取决于系统。
int arr[N];
在文件范围内(或前面有 static
)或在堆栈上,则
int arr[N];
进入静态内存。
静态内存 int arr[N];
的分配成本最低(在大小开销和分配时间方面),但它永远不会被释放,并且内存不会始终是缓存本地的。
如果 int arr[N];
在块内(并且前面没有 static
),则 int arr[N];
进入堆栈。这个内存几乎肯定是缓存本地的,但如果 N
很大并且你的堆栈有限(或者你有堆栈溢出的风险)或者如果 [=17 的生命周期,你可能不希望使用这种形式=] 需要超过它的包含块。
malloc
的内存需要一些时间来分配(几十到几百ns),它可能会带来一些大小开销,并且分配可能会失败,但是你可以稍后free
内存它会一直保留到您执行 free
为止。它也可以调整大小(通过 realloc
)而无需复制内存。缓存位置方面,它有点像静态内存(即,该块可能远离堆栈的缓存热端)。
所以这些是考虑因素:生命周期、堆栈大小、分配时间、大小开销、自由能力,可能还有缓存位置。
最后的考虑可能是 C 的一个特殊特性:有效类型。声明的数组具有固定的有效类型,因此不能在不违反 C 的严格别名规则的情况下重新键入,但 malloc
的内存可以。换句话说,您可以使用 malloc
块作为您自己的通用分配器的后备存储,但严格来说,声明的 char
数组不能以这种方式使用。