简体   繁体   English

C指针(数组)的内存分配(十六进制)

[英]C pointers (arrays) memory allocation (hexadecimal)

I was playing with memory addressing in C and I encountered a situation I cannot fully explain. 我在用C语言进行内存寻址,遇到无法完全解释的情况。

EDIT: the code is compiled by a c++ compiler. 编辑:代码是由c ++编译器编译的。 (g++) (克++)

#include <cstdlib>
#include <cstdio>
int main()
{

    int* array[10]; //array of pointers to integers

    for(int i = 0; i < 10; i++)
        {
            array[i] = (int*)malloc(sizeof(int));
            *(array[i]) = i;
        }


    printf("\n");
    for(int i = 0; i < 10; i++)
       {
            printf("%d:%p\n", *(array[i]), array[i]);
       }
    printf("\n");




    int arr[10]; //array of integers

    int* start = arr; //pointer to the first element (array decay)
    for(int i = 0; i < 10; i++)
        arr[i] = i;

    printf("\n");
    for(int i = 0; i < 10; i++)
    {
        printf("%d:%p\n", *(start + i), start + i);
   }
   printf("\n");

 return 0;
 }

Everything compile and works however I get strange memory addresses. 一切都可以编译并运行,但是我得到了奇怪的内存地址。 For the first array I get something like: 对于第一个数组,我得到类似:

0:0x23e4010
1:0x23e4030 (32 bits between the addresses which is correct)

but for the second array I get: 但是对于第二个数组,我得到:

0:0x7ffdaf876290
1:0x7ffdaf876294 (only 4 bits? or maybe they are bytes - but why the long addresses???)

Can someone explain this? 有人可以解释吗? (also is there a function to transform the hex into decimal without any effort?) (还有是否可以不费力地将十六进制转换为十进制的函数?)

In the first instance, your array is an array of pointers. 首先,您的数组是一个指针数组。 Each element is a pointer and, when you allocate memory for each pointer to point to, it's completely unrelated to the memory you allocate for other pointers in that array. 每个元素都是一个指针,当您为每个指向的指针分配内存时,它与为该数组中的其他指针分配的内存完全无关。 They are in fact 32 bytes apart in this case, but that's just pure chance. 在这种情况下,它们实际上相距32 个字节 ,但这只是纯粹的机会。

In the latter case, you are creating an array of integers which are all bunched together, or "contiguous", in memory. 在后一种情况下,您将创建一个整数数组,这些整数在内存中全部聚集在一起或“连续”。 They will be adjacent, hence the pattern you see when you print their addresses, which are 4 bytes apart. 它们将是相邻的,因此在打印它们的地址(相隔4 个字节)时会看到模式。 Evidently, int on your system is 4 bytes wide (which is fairly common still). 显然,系统上的int为4字节宽(这仍然很常见)。

The "long addresses" are due to your use of dynamic allocation: that'll be the area in virtual memory where your system happens to hold the heap. “长地址”是由于您使用了动态分配而来的:这将是虚拟内存中系统恰好保留堆的区域。 Nothing to worry about. 完全不用担心。

So there's nothing "strange" about it. 因此,没有什么“奇怪”的。

Int for Array uses 1byte. 数组的Int使用1byte。

Let address of: - array[0]=5000 设以下地址:-array [0] = 5000

Then - array[1]=5001 - array[2]=5002 - array[3]=5003 - array[4]=5004 - array[5]=5005 - array[6]=5006 - array[7]=5007 - array[8]=5008 - array[9]=5009 然后-数组[1] = 5001-数组[2] = 5002-数组[3] = 5003-数组[4] = 5004-数组[5] = 5005-数组[6] = 5006-数组[7] = 5007 -数组[8] = 5008-数组[9] = 5009

Now, You're assigning pointer. 现在,您正在分配指针。 Then address of Pointer: 然后指针的地址:

  • *(array[0])=5010 *(数组[0])= 5010
  • *(array[1])=5011 *(阵列[1])= 5011
  • *(array[2])=5012 *(阵列[2])= 5012
  • *(array[3])=5013 *(阵列[3])= 5013
  • *(array[4])=5014 *(阵列[4])= 5014
  • *(array[5])=5015 *(阵列[5])= 5015
  • *(array[6])=5016 *(阵列[6])= 5016
  • *(array[7])=5017 *(阵列[7])= 5017
  • *(array[8])=5018 *(阵列[8])= 5018
  • *(array[9])=5019 *(阵列[9])= 5019

Here You can easily see that the difference between array[i] and *(array[i]) will be always 10bytes. 在这里,您可以轻松地看到array [i]和*(array [i])之间的差异始终为10个字节。 This is because when any Array is called then only it allocates memory total size at once. 这是因为当调用任何Array时,只有它一次分配内存总大小。

Now addresses of second: Array arr is defined but not called. 现在第二个地址:数组arr已定义但未调用。 Hence, no memory will be allocated till you call that arr Here, calling is for defining it 因此,没有内存将被分配,直到你把那个叫ARR 这里,通话是其定义

Now, first line says: 现在,第一行说:

int arr[10];

That only defined the base address. 那只定义了基地址。 Then you gave that base address to *start by: 然后,您将该基本地址提供给* start by:

int* start=arr;

Hence pointer gets that address. 因此,指针获取该地址。 Clearly, Let: Address of: 显然,让:地址:

  • arr[0]=5020 Then: arr [0] = 5020然后:
  • *(start+0)=5020 *(START + 0)= 5020

Since, it is a pointer (not an Array) hence will take 4bytes. 由于它是一个指针(不是数组),因此将占用4个字节。 Similarly, all addresses range will be: 同样,所有地址范围将是:

  • arr[0]=5020 - 5023 arr [0] = 5020-5023
  • arr[1]=5024- 5028 And so on.. arr [1] = 5024- 5028依此类推。

Explanation to Allocation: 分配说明:

  • Whenever we define an Array, it defines only the Base Address . 每当我们定义数组时,它仅定义基地址 Ex: 例如:

    int a[10]; int a [10];

Will allocate base address, ie, starting address, ie, address for a[0]; 将分配基地址,即起始地址,即a [0]的地址;

  • Whenever you define a pointer, it will also allocate base address only. 每当定义指针时,它也将仅分配基地址。

  • Difference lies only in the allocation, ie, array allocates 1byte and pointer allocates 4byte (GCC/ Linux/32bit Compiler) for a Pointer. 区别仅在于分配,即数组为指针分配1个字节,指针分配4个字节(GCC / Linux / 32位编译器)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM