Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么C中的64位指针只使用4字节而不是预期的8字节? 我试图成为一个真正的人,从C++到C指针,Maloc有时会变得混乱。我使用的是没有任何标志的gcc,64位linux_C_Linux_Pointers_64 Bit - Fatal编程技术网

为什么C中的64位指针只使用4字节而不是预期的8字节? 我试图成为一个真正的人,从C++到C指针,Maloc有时会变得混乱。我使用的是没有任何标志的gcc,64位linux

为什么C中的64位指针只使用4字节而不是预期的8字节? 我试图成为一个真正的人,从C++到C指针,Maloc有时会变得混乱。我使用的是没有任何标志的gcc,64位linux,c,linux,pointers,64-bit,C,Linux,Pointers,64 Bit,因此,我的第一个问题是: int* c; int* d; void* shared = malloc(sizeof(int)*2); c = shared; d = shared + sizeof(int); *c = 123; *d = 321; printf("c: %p, *c: %i\n", (void*)c, *c); printf("d: %p, *d: %i\n", (void*)d, *d); printf("sizeof(c): %lu, sizeof(d): %lu\n",

因此,我的第一个问题是:

int* c;
int* d;
void* shared = malloc(sizeof(int)*2);
c = shared;
d = shared + sizeof(int);
*c = 123;
*d = 321;

printf("c: %p, *c: %i\n", (void*)c, *c);
printf("d: %p, *d: %i\n", (void*)d, *d);
printf("sizeof(c): %lu, sizeof(d): %lu\n", sizeof(c), sizeof(d));
产出: c:0x1c97050,*c:123 d:0x1c97054,*d:321 sizeofc:8,sizeofd:8

将两个内存地址转换为十进制并检查它们的差异得到4。 这意味着它们在内存中彼此相差4字节? 这意味着int用4个字节表示,sizeofint=4

但是,我想任何类型的指针,但在我们的例子中,由于64位内存,int的指针是用8个字节表示的? 这意味着我犯了一个错误,只将4个字节替换为所需的8个字节int而不是int*

但是为什么我没有丢失任何数据呢?纯粹的巧合/运气

为存储在那里的数据类型分配足够的空间,即32位int。这很好


结果是一个64位地址,存储在c和/或d中,占用8个字节。编译器更正确地分配了存储,当您声明c和d时,它会在运行时为您安排分配,并且它足够聪明,可以为这两个变量提供sizeofint*。您没有导致c和d的内存布局出现问题,因为您的malloc调用不会影响代码中声明的变量的布局。

两个int*之间的差异给出了int*的大小,而不是int*的大小。在您的系统中,int*的大小为8

要打印int*的大小,必须执行以下操作:

 printf("%zu\n", sizeof (int *));

这或多或少是您在示例中所做的,并且显示了值8。

内存分配中没有重叠,这就是为什么您没有丢失数据,如果您想实现数据丢失场景,请尝试此操作。 这里*c是指向long的指针,*d是指向int的指针

void main()
{

  long int *c;
  int *d;
  void *shared = malloc(sizeof(int)*2);
  c= shared;
  d= shared + sizeof(int);

  printf("size of int in this machine = %d\n",sizeof(int));
  printf("size of long in this machine = %d\n",sizeof(long));

  *d = 0xCDCDCDCD;
  *c = 0xABABABABABAB;

  printf("c: %p, *c: %x\n", (void*)c, *c);
  printf("d: %p, *d: %x\n", (void*)d, *d);
  printf("sizeof(c): %lu, sizeof(d): %lu\n", sizeof(c),sizeof(d));
}
这里*c=0xababab将进入*d的内存中并在那里擦除值

输出:

size of int in this machine = 4
size of long in this machine = 8
c: 0x7feb81c04ac0, *c: abababab
d: 0x7feb81c04ac4, *d: abab
sizeof(c): 8, sizeof(d): 8

指针对象c和d占用的存储空间与指针指向的数据对象占用的存储空间无关

这是一个假设的内存图,显示了这些值是如何通过稀薄的空气构成的c和d的地址进行布局的,假设采用大端布局:

  Item            Address                0x01  0x02  0x03  0x04
  ----            -------                ----  ----  ----  ----
shared            0x0000000001c97050       00    00    00    7b
                  0x0000000001c97054       00    00    01    41
                  ...    
     c            0x000000fffff86400       00    00    00    00
                  0x000000fffff86404       01    c9    70    50
     d            0x000000fffff86408       00    00    00    00
                  0x000000fffff8640c       01    c9    70    54
在malloc调用中,您分配了存储2个int对象的空间,每个int对象占用4个字节。共享的第一个元素(位于地址0x0000000001c97050)存储4字节值123,第二个元素(位于地址0x0000000001c97054)存储4字节值321

指针c位于地址0x000000fffff86400处,它存储共享的第一个元素0x0000000001c97050的8字节地址。类似地,位于地址0x000000fffff86408处的指针d存储shared的第二个元素的地址,即0x0000000001c97054

TL;DR—您为数据分配了正确的内存量,这才是最重要的

无端的咆哮

我正努力成为一个真正的人,从C++到C<P/P 学习C不会让你变得有男子气概;它让你成为一个懂C的人。围绕C语言、C编程和C程序员,有很多糟糕的神话。是的,它的低级抽象迫使你时刻保持警觉,但这并不能让你变得有男子气概,它只会让你变得偏执。对于相当狭窄的应用程序领域系统编程、非图形服务器端处理等来说,C是正确的工具,但对于一般的应用程序编程来说,它已经被更易于使用的语言所取代


另外,./p>为什么使用C使人更为灵活?也可以在C++中使用指针——它们的工作方式完全相同。你已经在两个int的空间中存储了两个int,当然,你可以做到,指针和它指向的对象之间有区别吗?@ USER3528 438:不在标准的遵从模式下。实际上,标准不允许对void*进行操作,我认为这是gcc的一个更负面的扩展,只是为了保护对char*的一些强制转换。但是,如果没有明确要求,则应假定符合标准。