sintaxis memoria estructuras ejemplos dinamica array c++ c pointers memory sizeof

c++ - memoria - ¿Es el sizeof(algún puntero) siempre igual a cuatro?



sizeof() c (17)

Por ejemplo: sizeof(char*) devuelve 4. Al igual que int* , long long* , todo lo que he intentado. ¿Hay alguna excepción a esto?


Además de las diferencias de 16/32/64 bits, pueden ocurrir cosas aún más extrañas.

Ha habido máquinas donde sizeof (int *) será un valor, probablemente 4 pero donde sizeof (char *) es mayor. Las máquinas que naturalmente direccionan palabras en lugar de bytes tienen que "aumentar" los punteros de caracteres para especificar qué parte de la palabra realmente desea para implementar correctamente el estándar C / C ++.

Esto es ahora muy inusual ya que los diseñadores de hardware han aprendido el valor de la direccionabilidad de bytes.


Además de lo que la gente ha dicho sobre los sistemas de 64 bits (o lo que sea), hay otros tipos de punteros que punteros a objetos.

Un puntero a miembro puede ser de casi cualquier tamaño, dependiendo de cómo esté implementado por su compilador: no necesariamente son del mismo tamaño. Pruebe un puntero a miembro de una clase POD y luego un puntero a miembro heredado de una de las clases base de una clase con varias bases. Qué divertido.


El tamaño del puntero depende básicamente de la arquitectura del sistema en el que se implementa. Por ejemplo, el tamaño de un puntero en 32 bits es 4 bytes (32 bits) y 8 bytes (64 bits) en máquinas de 64 bits. Los tipos de bits en una máquina no son más que direcciones de memoria, que puede tener. Las máquinas de 32 bits pueden tener 2^32 espacios de direcciones y las máquinas de 64 bits pueden tener hasta 2^64 espacios de direcciones. Por lo tanto, un puntero (variable que apunta a una ubicación de memoria) debe poder apuntar a cualquiera de las direcciones de memoria ( 2^32 for 32 bit and 2^64 for 64 bit ) que una máquina contiene.

Por esta razón, vemos que el tamaño del puntero es de 4 bytes en una máquina de 32 bits y de 8 bytes en una máquina de 64 bits.


El tamaño del puntero y el int es de 2 bytes en el compilador Turbo C en una máquina con Windows de 32 bits.

Así que el tamaño del puntero es específico del compilador. Pero, en general, la mayoría de los compiladores se implementan para admitir una variable de puntero de 4 bytes en una variable de puntero de 32 bits y de 8 bytes en una máquina de 64 bits.

Así que el tamaño del puntero no es el mismo en todas las máquinas.


En Win64 (Cygwin GCC 5.4) , veamos el siguiente ejemplo:

Primero, prueba la siguiente estructura:

struct list_node{ int a; list_node* prev; list_node* next; }; struct test_struc{ char a, b; };

El código de prueba está abajo:

std::cout<<"sizeof(int): "<<sizeof(int)<<std::endl; std::cout<<"sizeof(int*): "<<sizeof(int*)<<std::endl; std::cout<<std::endl; std::cout<<"sizeof(double): "<<sizeof(double)<<std::endl; std::cout<<"sizeof(double*): "<<sizeof(double*)<<std::endl; std::cout<<std::endl; std::cout<<"sizeof(list_node): "<<sizeof(list_node)<<std::endl; std::cout<<"sizeof(list_node*): "<<sizeof(list_node*)<<std::endl; std::cout<<std::endl; std::cout<<"sizeof(test_struc): "<<sizeof(test_struc)<<std::endl; std::cout<<"sizeof(test_struc*): "<<sizeof(test_struc*)<<std::endl;

La salida es a continuación:

sizeof(int): 4 sizeof(int*): 8 sizeof(double): 8 sizeof(double*): 8 sizeof(list_node): 24 sizeof(list_node*): 8 sizeof(test_struc): 2 sizeof(test_struc*): 8

Puedes ver que en 64 bits, sizeof(pointer) es 8 .


En general, sizeof (prácticamente cualquier cosa) cambiará cuando compile en diferentes plataformas. En una plataforma de 32 bits, los punteros son siempre del mismo tamaño. En otras plataformas (64 bits es el ejemplo obvio) esto puede cambiar.


Incluso en una plataforma llana x86 de 32 bits, puede obtener una variedad de tamaños de punteros, pruebe esto como ejemplo:

struct A {}; struct B : virtual public A {}; struct C {}; struct D : public A, public C {}; int main() { cout << "A:" << sizeof(void (A::*)()) << endl; cout << "B:" << sizeof(void (B::*)()) << endl; cout << "D:" << sizeof(void (D::*)()) << endl; }

Bajo Visual C ++ 2008, obtengo 4, 12 y 8 para los tamaños de la función de punteros a miembros.

Raymond Chen habló de esto here .


La garantía que obtienes es que sizeof(char) == 1 . No hay otras garantías, incluyendo ninguna garantía de que sizeof(int *) == sizeof(double *) .

En la práctica, los punteros serán del tamaño 2 en un sistema de 16 bits (si puede encontrar uno), 4 en un sistema de 32 bits y 8 en un sistema de 64 bits, pero no hay nada que ganar al confiar en un determinado tamaño.


La razón por la que el tamaño del puntero es de 4 bytes es porque está compilando para una arquitectura de 32 bits. Como señaló FryGuy, en una arquitectura de 64 bits verías 8.


Los punteros de 8 bits y 16 bits se utilizan en la mayoría de los microcontroladores de perfil bajo. Eso significa que cada lavadora, micro, nevera, televisores más viejos, e incluso los coches.

Se podría decir que no tienen nada que ver con la programación del mundo real. Pero aquí hay un ejemplo del mundo real: Arduino con 1-2-4k ram (dependiendo del chip) con punteros de 2 bytes.

Es reciente, barato, accesible para todos y vale la pena codificar.


No, el tamaño de un puntero puede variar según la arquitectura. Hay numerosas excepciones.


Por lo que recuerdo, se basa en el tamaño de una dirección de memoria. Entonces, en un sistema con un esquema de direcciones de 32 bits, sizeof devolverá 4, ya que son 4 bytes.


Si está compilando para una máquina de 64 bits, entonces puede ser 8.


Solo otra excepción a la lista ya publicada. En plataformas de 32 bits, los punteros pueden tomar 6, no 4 bytes:

#include <stdio.h> #include <stdlib.h> int main() { char far* ptr; // note that this is a far pointer printf( "%d/n", sizeof( ptr)); return EXIT_SUCCESS; }

Si compilas este programa con Open Watcom y lo ejecutas, obtendrás 6, porque los punteros lejanos que admite consisten en un desplazamiento de 32 bits y valores de segmento de 16 bits


Solo por su interés histórico y completo, en el mundo de 64 bits existían diferentes convenciones de plataformas sobre los tamaños de los tipos largos y largos, denominados LLP64 y LP64, principalmente entre sistemas de tipo Unix y Windows. Un estándar antiguo llamado ILP64 también tenía un ancho de int = 64 bits.

Microsoft mantuvo LLP64 donde longlong = 64 bit wide, pero mucho tiempo permaneció en 32, para facilitar la portabilidad.

Type ILP64 LP64 LLP64 char 8 8 8 short 16 16 16 int 64 32 32 long 64 64 32 long long 64 64 64 pointer 64 64 64

Fuente: https://.com/a/384672/48026


Técnicamente hablando, el estándar C solo garantiza ese sizeof (char) == 1, y el resto depende de la implementación. Pero en las arquitecturas x86 modernas (por ejemplo, los chips Intel / AMD) es bastante predecible.

Probablemente haya escuchado que los procesadores se describen como de 16 bits, 32 bits, 64 bits, etc. Esto generalmente significa que el procesador utiliza N bits para los enteros. Dado que los punteros almacenan las direcciones de memoria y las direcciones de memoria son enteros, esto le indica efectivamente cuántos bits se van a utilizar para los punteros. El tamaño generalmente se mide en bytes, por lo que el código compilado para los procesadores de 32 bits informará que el tamaño de los punteros es 4 (32 bits / 8 bits por byte), y el código para los procesadores de 64 bits informará que el tamaño de los punteros es 8 (64 bits / 8 bits por byte). Aquí es donde surge la limitación de 4 GB de RAM para los procesadores de 32 bits: si cada dirección de memoria corresponde a un byte, para hacer frente a más memoria, se necesitan números enteros mayores que 32 bits.


Un puntero es solo un contenedor de una dirección. En una máquina de 32 bits, su rango de direcciones es de 32 bits, por lo que un puntero siempre será de 4 bytes. En una máquina de 64 bits, si tiene un rango de direcciones de 64 bits, un puntero será de 8 bytes.