为什么数组中的指针没有存储在连续的内存中

时间:2016-03-14 14:05:17

标签: c++ arrays pointers

所以我一直试图弄清楚这一点,但我无法绕过它。

如果我有这样的数组:

int numbers[] = {0,1,2,3,4,5,6,7,8,9};

每个数字将存储在连续的内存中,彼此之间的距离为int(我的系统上为4个字节)。所以,如果我有一个像这样的指针数组:

int* pNumbers[] = {new int(0), new int(1), new int(2)};

我希望它们存储在内存中,指针之间的距离(我的系统上有4个字节),但事实并非如此。相反,它们以64字节的距离存储。另外,如果我创建一个由指向包含int和bool的Struct的指针组成的数组,则该距离为72个字节。

有人可以解释这里发生的事情以及如何确定阵列中每个元素之间的距离。

4 个答案:

答案 0 :(得分:4)

int* pNumbers[]

这声明了连续 int *元素的数组。它们将相隔sizeof( int * )个字节。根据平台的不同,可能介于28之间,但绝大多数都不是64

... = {new int(0), new int(1), new int(2)};

使用指向已分配内存的指针初始化元素,使用给定值初始化内存。根据您的实现,那些指向内存的指针可能与sizeof( int ),相距甚远或不连续一样紧密。确切的数字未指定。

因此,数组中的int * 元素将是连续的,并且与sizeof( int * )完全相同。他们可以在任何地方指向

这就是为什么评论员(包括我自己)怀疑您的测量存在问题,即您打印指向的地址,而不是指针的地址

答案 1 :(得分:1)

你做错了观察。

对于int数组,你是对的:

  

每个数字都将存储在连续内存中,其距离为int(我系统上为4个字节)

类似地,对于指针数组,每个指针将存储在连续的内存中,它们之间的距离为sizeof(int*)。这就是数组如何工作的。

我认为你看到的是指针的价值,但你应该看看他们的地址

int数组的情况下,您没有查看数组元素的值(这些只是值增加1的整数,因为那就是你的意思存储在数组中)你查看了元素的地址。

您需要对指针数组执行相同操作。不要查看指针的值(那些是堆new为每个int分配内存的地址,因为那是你存储在数组中的内容),看看在指针的地址。

堆指针的值可能具有相当任意的值,具体取决于系统上malloc的实现细节。您碰巧观察到它们相距64个字节,但这并不能保证,您无法依赖它。如果你有一个执行其他堆分配和解除分配的更复杂的程序,你可能会发现一个完全不同的模式,而不是每次增加固定数量的三个值。

答案 2 :(得分:-1)

如果你调用“new int(0)”,你告诉操作系统(windoes,linux,osx等)给你4个字节(sizeof(int))的数据,你可以存储你的整数。操作系统可以随意给你内存中的任何空间。

为什么你的操作系统会给你64个字节的内存点我无法分辨。

结果应根据您运行测试的系统而有所不同。

答案 3 :(得分:-1)

这是设计的。当您从堆中手动分配内存时,C ++运行时提供了一个内存管理器(在操作系统的内存管理器之上),并且不保证它获取您分配的内存。

但是,在现代C ++中,您确实希望尽可能避免分配内存。首先,动态分配int是非常昂贵的,因为在64位模式下,每个4字节的int将需要8个字节用于指针。

相反,对于int的动态数组,请使用std :: vector。标准库提供了很大的灵活性,大部分/全部开销都将在这种简单的情况下编译出来。