数组在内存中是如何存储的?

17

我有一个简单的程序,它将一个数组初始化为:

int a[]={10,20,30,40,50};   
char *p;
p=(char*)a;

现在我想通过指针p访问每个字节的值。为此,我需要知道:数组是如何存储在内存中的?它是存储在堆栈还是堆中?


也许我错过了什么,但是为什么你需要知道它是存储在堆栈还是堆中?你尝试过p[0]吗?也许你可以通过说明你遇到的问题来提出一个问题,这样我们就有了一个起点... - Ray
正如@Ray所说,根据你正在做的事情,它可能“无关紧要”...并且可能在各种方式上依赖于编译器,而不是实现细节。 无论哪种方式,这些都不是唯一的两个存储类别...至少在C++中是这样(刚刚注意到这是一个C问题,我对C的规范知之甚少...其他人可能会有更合适的链接)。 不过,这可能会有用:http://www.gotw.ca/gotw/009.htm - HostileFork says dont trust SE
4
“这种问题确实是 C 语言的核心所在。” -- 不,不是。 “你为什么需要知道它是存储在堆栈还是堆中?”-- 没有提到这样的需求。该问题似乎与字节顺序有关。 - Jim Balter
1
@som,你为什么想要访问int数组的字节?你将得到的字节数是sizeof(a)*sizeof(int),它们的顺序取决于机器架构。 - Jim Balter
4个回答

36

数组将其元素存储在连续的内存位置中。
如果您在本地创建了数组,则它将位于堆栈上。元素存储的位置取决于存储说明
例如:
全局或静态声明的数组与本地声明的数组具有不同的存储说明。从技术上讲,where部分是实现定义的,但通常实现会使用类似的用法模式。

  • 本地数组通常会在堆栈上创建,而
  • 全局或静态数组通常会在bss/data段上创建,并且
  • 动态创建的数组会在上创建。

7

由于我目前还不能添加评论,以下是我的建议:

如果您只想知道内存是在堆栈上还是在堆上,那么请阅读其他答案,它们比我更了解。

如果您想确切地知道值的位置,您可以打印地址:

printf("address at a[0] = %p\n", (void *)&a[0]);
printf("address at p[0] = %p\n", (void *)&p[0]);

你会注意到相同的答案。但是,请看

printf("address at a[1] = %p\n", (void *)&a[1]);
printf("address at p[1] = %p\n", (void *)&p[1]);

这是一个有趣的小练习。 只是为了好玩,运行下面的代码并查看结果:

 p[2] = 'a';
 printf("a[0] is %d\n", a[0]);
 printf("a[1] is %d\n", a[1]);
 printf("p[2] is %d\n", p[2]);
 putchar(p[2]);

1
+1 对于SO是新手并建议尝试实验的做法表示赞同,这是探索和调查的好方法。然而,人们应该始终记住编译器是不同的。因此,仅仅因为在实验中观察到一种模式,并不意味着它是“真理”。唯一的“真理”在于规范的措辞,它作出了一些保证...但除了编译器错误外,规范仍然严重依赖于“未定义行为”的支持。另外,习惯用语是“two cents”(像钱一样),而不是“two sense”,虽然后者很有趣。 :) http://en.wikipedia.org/wiki/Undefined_behavior - HostileFork says dont trust SE
@HostileFork 你的观点很有道理。作为一名新手程序员,由于谷歌似乎总是指向SO,我决定应该加入!“cents”的问题解决得不错! - NickO

3

静态创建的数组会放在栈上或二进制文件的 .data/.bss 段中。动态创建的数组(使用 newmalloc)将被分配在堆上。


-3

首先,您的指针必须是 int 类型。 数组只是一组整数,在内存中保存为单个整数,但在一行中。 一个整数在内存中有 4 字节,因此您可以通过将指针增加 4 来访问数组的每个值。

int *p = (int*)a;
for(i = 0; i < 5; i++) {
    p += 4;
    printf("%d ", *p);
}

4
由于原帖提到想要访问每个字节,明确使用了char指针和char转换,因此将指针类型更改为int类型是没有意义的。此外,int类型不一定是4个字节,将指针加上4也是非常错误的,因为加数会乘以int类型的大小。 - Jim Balter

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