3

1.两个维度在内存中是如何存储的,它们是连续的吗?(我的意思是int[M][N],不是动态分配,我认为int[M][N]发生在栈区,所以是连续的,不是吗?)

2.malloc分配的区域一定是连续的吗?

3.如果不需要动态分配内存空间,应该在哪里使用?堆栈或堆。例如,我想要一个 char 数组来存储 10000 个字符,所以我应该使用:

char a[10000];

或者

char *a = calloc(sizeof(char),10000);

“函数调用栈”和变量栈是在同一个区域吗?在同一个栈还是不同?

4

5 回答 5

4

int numbers[m][n]n 中是内存中的连续整数,例如numbers[0][0]后跟numbers[0][1].

另一方面,假设 n=10,然后numbers[m][9]numbers[m+1][0]

malloc返回连续的内存。你决定如何使用它。

堆栈上的 10000 字节数组没有问题,除非该函数是递归的,并且(如 Carey 所指出的)除非您在小型堆栈环境中进行开发,即。嵌入。

是的,调用堆栈和局部变量是相同的。

于 2013-02-22T19:20:16.327 回答
1

当你分配某事[a][b] 时它是连续的吗?

是的

当我制作平铺地图的游戏时,我什至会在渲染中使用指针访问平铺。

即:如果地图是 10x10,我将使用arrayName[14]例如渲染图块 [1][3]。

还要记住使用这个事实,在某些地方,[b] 而不是 [a] 将完全在内存中,如果您依赖来自 FORTRAN(如 CBLAS)或一些特定的设备和情况(比如一些带有一些特定驱动程序的 GPU)。

使用malloc的时候,一定是连续的吗?

是的,如果连续内存不可用,它将失败。这是一个非常常见的错误,因为存在总可用内存,而没有考虑内存碎片,所以期望程序可以运行。

我曾经做过一个游戏,因为它有 30mb 的内存但无法加载 16mb 的图像而无法运行……当时我没有意识到我的代码导致的内存碎片导致没有 16mb 的块可用。

如果不需要动态分配,我应该使用堆栈还是堆?

在 C 中,动态分配通常意味着堆分配,早期的 C 书籍甚至明确指出malloc和类似的函数系列(calloc包括)仅在堆上运行。而自动分配尝试使用堆栈。

于 2013-02-22T19:19:03.117 回答
1
  1. 内存是连续的。一个维度中的所有项目将是连续的,然后是下一个维度。

  2. 是的。一次调用分配的所有内存malloc()都是连续的。

  3. 如果您需要大量内存,我建议动态分配它。对于更少的内存,您可以静态分配。malloc() 确实使用堆。我不推荐堆栈,除非只有非常少量的内存。

于 2013-02-22T19:16:59.980 回答
0

C 不支持二维数组。它支持数组数组和数组指针数组,两者都可以像二维数组一样使用,但它们根本不一样,它们都不是真正的二维数组。

数组占用连续的内存位置。所以当你有一个数组数组时,每个子数组都是单独连续的,这些数组一个接一个地布置在内存中,使整个事情是连续的。

当您有一个指向数组的指针数组时,每个子数组都是单独连续的,但子数组不需要彼此连续——它们可能分布在整个内存中。顶级数组是连续的,但它只包含指向子数组的指针,而不包含子数组本身。

在任何一种情况下,您都可以从“二维”数组中获取单个(行)子数组,但是没有简单的方法来获取列数组——您需要创建一个单独的数组并从每个单独的行数组中复制值如果你想要那种形式。

于 2013-02-22T19:31:30.633 回答
-1

1)老实说,我不知道。

2) 是的,malloc 分配的区域在虚拟地址空间中是连续的。这可以通过简单的思维练习来推断;给定一个指针,如果你遍历整个空间,你总是将指针加一并且仍然得到有效数据。请注意,可能会返回不连续的物理映射,尽管这一切都在低于您的级别进行处理(即在操作系统和处理器的 TLB 中)。

3) 通常,使用堆。它通常是一个较大的段,特别是如果您使用线程(即我刚刚运行的测试显示 pthreads 的默认堆栈大小为 8MB)。

至于3)的第二部分,函数调用栈和变量栈一样。当您静态创建变量时(即不通过malloc),它存在于包含函数的堆栈框架中,当然它驻留在堆栈中。有关这方面的更多信息,请查看 .

于 2013-02-22T19:20:19.347 回答