1.两个维度是如何存储在内存中的,它们是连续的吗?(我指的是int[M][N],而不是动态分配,我认为int[M][N].发生在堆栈区域,所以是连续的,不是吗?)
2.malloc分配的区域必须是连续的吗?
3.如果不需要动态分配内存空间,我应该使用哪里?堆栈或堆。例如我想要一个字符数组来存储10000个字符,所以我应该使用:
char a[10000];
或
char *a = calloc(sizeof(char),10000);
"函数调用堆栈"是否与变量堆栈位于同一区域??在同一堆还是不同的?
在int numbers[m][n]
中,n是内存中的连续int,例如numbers[0][0]
后面跟着numbers[0][1]
。
另一方面,假设n=10,则numbers[m][9]
后面跟着numbers[m+1][0]
。
malloc
返回连续内存。你决定如何使用它。
堆栈上的10000字节数组是没有问题的,除非函数是递归的,并且(正如Carey所指出的)除非您在小堆栈环境中开发,即嵌入式环境。
是的,调用堆栈和局部变量是相同的。
-
内存是连续的。一个维度中的所有项目都是连续的,后面跟着下一个维度。
-
是的。对
malloc()
的单个调用所分配的所有内存都是连续的。 -
如果您需要大量内存,我建议您动态分配。对于较少的内存,可以静态分配。
malloc()
确实使用堆。除了极少量的内存外,我不推荐使用堆栈。
当您分配某个东西[a][b]时,它是连续的吗
是
当我制作带有平铺贴图的游戏时,我甚至会在渲染时使用指针访问平铺。
Ie:如果贴图是10x10,我会使用arrayName[14]
来渲染tile[1][3]。
还要记住,在某些地方,[b]而不是[a]是完全在内存中的,如果你依赖来自FORTRAN(如CBAS)的代码,或者在某些特定的设备和情况下(如带有某些特定驱动程序的GPU),这可能会导致错误。
当您使用malloc时,它必须是连续的
是的,如果连续内存不可用,它将失败。在没有考虑内存碎片的情况下,由于存在总的可用内存而期望程序能够工作,这是一个非常常见的错误。
我曾经做过一个游戏,它失败了,因为它有30mb的内存,但无法加载16mb的图像。。。当时我没有意识到,我的代码导致的内存碎片导致没有16mb的块可用。
如果不需要动态分配,我应该使用堆栈还是堆
在C中,动态分配通常意味着堆分配,早期的C书甚至明确表示malloc
和类似的函数族(包括calloc
)只在堆上操作。而自动分配尝试使用堆栈。
C不支持2D阵列。它支持数组数组和指向数组的指针数组,两者都可以像2D数组一样使用,但它们根本不一样,而且都不是真正的2D数组。
数组占用连续的内存位置。因此,当你有一个数组数组时,每个子数组都是单独连续的,这些数组一个接一个地排列在内存中,使整个数组连续。
当你有一个指向数组的指针数组时,每个子数组都是单独连续的,但子数组不需要彼此连续——它们可能分布在整个内存中。顶级数组是连续的,但它只包含指向子数组的指针,而不包含子数组本身。
在任何一种情况下,您都可以从"2D"数组中获得单个(行)子数组,但要获得列数组,没有简单的方法——您需要创建一个单独的数组,并将值从每个单独的行数组中复制出来,如果您想要的话。
1)老实说,我不知道。
2) 是的,malloc分配的区域在虚拟地址空间中是连续的。这可以通过一个简单的思考练习来推断;给定一个指针,如果您在整个空间上迭代,您总是将指针递增一,仍然可以获得有效的数据。不过,请注意,返回不连续的物理映射是可能的,尽管这都是在低于您的级别(即在操作系统和处理器的TLB内)处理的。
3) 通常,使用堆。它通常是一个较大的段,,尤其是,如果您使用线程(即,我刚刚运行的一个测试显示pthreads的默认堆栈大小为8MB)。
至于3)的第二部分,函数调用堆栈与变量堆栈相同。当您静态地创建一个变量(即不通过malloc
)时,它存在于包含函数的堆栈框架中,当然堆栈框架位于堆栈上。有关这方面的更多信息,请查看的堆栈约定。