• Sábado 14 de Diciembre de 2024, 23:54

Autor Tema:  Cuidao Con Los Punteros  (Leído 5402 veces)

ichigo15

  • Miembro activo
  • **
  • Mensajes: 37
    • Ver Perfil
Cuidao Con Los Punteros
« en: Martes 23 de Octubre de 2007, 23:15 »
0
Reconozco que no soy un as en programación, ni tengo mucho nivel en c, pero he visto un error que se repite mucho:

cuando declaras "char *nombre_variable;

Asigna una dirección de memoria, punto, y que el contenido es de tipo char, es decir, q si no especificas nada, solo reserva memoria para un caracter.

Si quieres más memoria, pidesela con un malloc.
[size=109]Nadie elige su nombre, te lo ponen cuando naces, pero sí su nick


No eres responsable de la cara que tienes, pero sí de la que pones
[/size]

Eternal Idol

  • Moderador
  • ******
  • Mensajes: 4696
  • Nacionalidad: ar
    • Ver Perfil
Re: Cuidao Con Los Punteros
« Respuesta #1 en: Martes 23 de Octubre de 2007, 23:24 »
0
Eso no reserva nada ni asigna nada. Solo declaras una variable de tipo char * que esta apuntando a una direccion indefinida (muy probablemente invalida).

Nacional y Popular En mi país la bandera de Eva es inmortal.


Queremos una Argentina socialmente justa, económicamente libre y  políticamente soberana.
¡Perón cumple, Evita dignifica!


La mano invisible del mercado me robo la billetera.

ichigo15

  • Miembro activo
  • **
  • Mensajes: 37
    • Ver Perfil
Re: Cuidao Con Los Punteros
« Respuesta #2 en: Miércoles 24 de Octubre de 2007, 19:38 »
0
vale, reservas una dirección de memoria. Te reserva una direccion de memoria de 1 byte (estamos hablando de los char), pero supongamos que en la siguiente dirección, hay información valiosa, esa información te la cargas, x eso de utilizar el malloc, xq si la cosa va mal, t devuelve un error

Vaya, creo q ahora m exprese mejor :unsure:
[size=109]Nadie elige su nombre, te lo ponen cuando naces, pero sí su nick


No eres responsable de la cara que tienes, pero sí de la que pones
[/size]

Eternal Idol

  • Moderador
  • ******
  • Mensajes: 4696
  • Nacionalidad: ar
    • Ver Perfil
Re: Cuidao Con Los Punteros
« Respuesta #3 en: Miércoles 24 de Octubre de 2007, 19:52 »
0
Cita de: "ichigo15"
vale, reservas una dirección de memoria. Te reserva una direccion de memoria de 1 byte (estamos hablando de los char), pero supongamos que en la siguiente dirección, hay información valiosa, esa información te la cargas, x eso de utilizar el malloc, xq si la cosa va mal, t devuelve un error

Vaya, creo q ahora m exprese mejor :unsure:
Es tal y como lo dije antes, estas confundido y por eso al intentar reformular seguis diciendo algo incorrecto.

No se reserva ningun tipo de memoria dinamica de esa manera. Solo declaras una variable de tipo char * cuyo valor es incierto y si accedes a ella es muy probable que genere una excepcion no controlada por ser una direccion invalida.

Esto es un error:
Código: Text
  1.  
  2. char *var;
  3. *var = 'A';
  4.  
  5.  

No hace falta pasar al "siguiente" byte ya que no estas reservando nada de nada. El VC++ te muestra este warning:

warning C4700: uninitialized local variable 'var' used

Normalmente los punteros se inicializan a 0 siempre y eso te daria una excepcion indefectiblemente.

Nacional y Popular En mi país la bandera de Eva es inmortal.


Queremos una Argentina socialmente justa, económicamente libre y  políticamente soberana.
¡Perón cumple, Evita dignifica!


La mano invisible del mercado me robo la billetera.

ichigo15

  • Miembro activo
  • **
  • Mensajes: 37
    • Ver Perfil
Re: Cuidao Con Los Punteros
« Respuesta #4 en: Miércoles 24 de Octubre de 2007, 21:21 »
0
vaya Eternal Idol, sabes mas que mi profesora de programación (no es que lo diga en tono irónico, es que lo digo en serio)

Tendré que corregirme a mi mismo, que dije que hacer una declaración como char *variable, y luego hacer gets(variable) estaba mal, pero veo que no.

Bueno, supongo que cada dia se aprende una cosa mas.

Pos una pregunta: si haces esto:

char *var;
*var = 'A';

corrigeme si m ekivoco, pero t declaras un puntero (var), y luego dices, que el contenido de ese puntero (*var) cuya dirección es (var) sea 'A', es como si haces esto:

char *var, var2;
var2 = 'A';
*var=var2; //*var no es el contenido de "var"?

yo pensaba que eso estaba bien, pero parece que tengo un error de conceptos un poco grande.
[size=109]Nadie elige su nombre, te lo ponen cuando naces, pero sí su nick


No eres responsable de la cara que tienes, pero sí de la que pones
[/size]

Eternal Idol

  • Moderador
  • ******
  • Mensajes: 4696
  • Nacionalidad: ar
    • Ver Perfil
Re: Cuidao Con Los Punteros
« Respuesta #5 en: Miércoles 24 de Octubre de 2007, 21:31 »
0
Cita de: "ichigo15"
vaya Eternal Idol, sabes mas que mi profesora de programación (no es que lo diga en tono irónico, es que lo digo en serio)

Por ahi dicen muchos que el que sabe hace y el que no enseña. Como todos los dichos tiene parte de verdad ...

Cita de: "ichigo15"
Tendré que corregirme a mi mismo, que dije que hacer una declaración como char *variable, y luego hacer gets(variable) estaba mal, pero veo que no.

Por supuesto que eso tambien esta mal, ya que a gets se le debe pasar como parametro una direccion de memoria valida.

Cita de: "ichigo15"
corrigeme si m ekivoco, pero t declaras un puntero (var), y luego dices, que el contenido de ese puntero (*var) cuya dirección es (var) sea 'A', es como si haces esto:

Su direccion es indefinida no es var, al ser una variable local va en la pila y tendra lo que haya en la misma en ese momento.

Cita de: "ichigo15"
char *var, var2;
var2 = 'A';
*var=var2; //*var no es el contenido de "var"?

yo pensaba que eso estaba bien, pero parece que tengo un error de conceptos un poco grande.

Tampoco esta bien. La tercera linea es el problema. ¿A donde apunta var? Al inicializarla asi no lo sabes, proba a compilar ese codigo, seguro te da una excepcion no controlada.

Asi si funcionaria:
Código: Text
  1.  
  2. char *var, var2;
  3. var = new char;
  4. var2 = 'A';
  5. *var=var2;
  6.  
  7.  

Nacional y Popular En mi país la bandera de Eva es inmortal.


Queremos una Argentina socialmente justa, económicamente libre y  políticamente soberana.
¡Perón cumple, Evita dignifica!


La mano invisible del mercado me robo la billetera.

Enko

  • Miembro de PLATA
  • *****
  • Mensajes: 1562
  • Nacionalidad: 00
    • Ver Perfil
Re: Cuidao Con Los Punteros
« Respuesta #6 en: Miércoles 24 de Octubre de 2007, 21:31 »
0
Citar
char *var;
Hay una cosilla más para agregar.
El tamaño de "puntero a char" llamado "var" no es 1 bytes, es decir, no tiene el tamaño de un "char" sino de un "puntero a char"  que segun el sistema operativo, puede ser 16 (DOS),32bits = 4 bytes(Windows XP),64 bits (Vista version 64).

Eternal Idol

  • Moderador
  • ******
  • Mensajes: 4696
  • Nacionalidad: ar
    • Ver Perfil
Re: Cuidao Con Los Punteros
« Respuesta #7 en: Miércoles 24 de Octubre de 2007, 21:35 »
0
Cita de: "Enko"
Hay una cosilla más para agregar.
El tamaño de "puntero a char" llamado "var" no es 1 bytes, es decir, no tiene el tamaño de un "char" sino de un "puntero a char"  que segun el sistema operativo, puede ser 16 (DOS),32bits = 4 bytes(Windows XP),64 bits (Vista version 64).
Efectivamente, ULONG_PTR para los amigos  B)

Nacional y Popular En mi país la bandera de Eva es inmortal.


Queremos una Argentina socialmente justa, económicamente libre y  políticamente soberana.
¡Perón cumple, Evita dignifica!


La mano invisible del mercado me robo la billetera.

ichigo15

  • Miembro activo
  • **
  • Mensajes: 37
    • Ver Perfil
Re: Cuidao Con Los Punteros
« Respuesta #8 en: Jueves 25 de Octubre de 2007, 21:47 »
0
Cita de: "Enko"
Citar
char *var;
Hay una cosilla más para agregar.
El tamaño de "puntero a char" llamado "var" no es 1 bytes, es decir, no tiene el tamaño de un "char" sino de un "puntero a char"  que segun el sistema operativo, puede ser 16 (DOS),32bits = 4 bytes(Windows XP),64 bits (Vista version 64).
buf, ahora si que estoy perdido.... con lo feliz que era en mi ignorancia  :wacko: , ahora estoy un poco confuso, a ver, los procesadores de 32 bits, por ej, son para procesar instruccines de 32 bits (instrucciones como if, for, etc), mientras que las variables se alojan en memoria (RAM, por lo general). Con los datos y las instrucciones, el procesador hace su trabajo, pero no entiendo que tiene que ver que el SO utilice software de 32 o 64 bits, para que reserve 64 bits para un caracter en el vista de 64 bits, por ejemplo :wacko:
[size=109]Nadie elige su nombre, te lo ponen cuando naces, pero sí su nick


No eres responsable de la cara que tienes, pero sí de la que pones
[/size]

Eternal Idol

  • Moderador
  • ******
  • Mensajes: 4696
  • Nacionalidad: ar
    • Ver Perfil
Re: Cuidao Con Los Punteros
« Respuesta #9 en: Jueves 25 de Octubre de 2007, 21:52 »
0
Cita de: "ichigo15"
buf, ahora si que estoy perdido.... con lo feliz que era en mi ignorancia  :wacko: , ahora estoy un poco confuso, a ver, los procesadores de 32 bits, por ej, son para procesar instruccines de 32 bits (instrucciones como if, for, etc), mientras que las variables se alojan en memoria (RAM, por lo general). Con los datos y las instrucciones, el procesador hace su trabajo, pero no entiendo que tiene que ver que el SO utilice software de 32 o 64 bits, para que reserve 64 bits para un caracter en el vista de 64 bits, por ejemplo :wacko:
Otra vez, es que no se reserva memoria dinamica sino que una variable local esta en la pila y para poder APUNTAR a una direccion se necesita un determinado tamaño para poder direccionar a la misma:

Por ejemplo si tuvieras un puntero a la direccion 0xFF00FF00 no podes usar menos de 4 bytes para guardar esa direccion, por mas que sea un puntero a char y que solo el primer byte sea valido.

Y lo mismo si tenes una direccion que es 0xFF00FF00FF00FF00 no podes usar 4 bytes, necesitas 8.

Nacional y Popular En mi país la bandera de Eva es inmortal.


Queremos una Argentina socialmente justa, económicamente libre y  políticamente soberana.
¡Perón cumple, Evita dignifica!


La mano invisible del mercado me robo la billetera.

Enko

  • Miembro de PLATA
  • *****
  • Mensajes: 1562
  • Nacionalidad: 00
    • Ver Perfil
Re: Cuidao Con Los Punteros
« Respuesta #10 en: Jueves 25 de Octubre de 2007, 22:44 »
0
Citar
los procesadores de 32 bits, por ej, son para procesar instruccines de 32 bits (instrucciones como if, for, etc),
Las instrucciones if,while,for,etc... son instrucciones de un lenguaje de alto nivel, como C++ no del procesador.
Citar
mientras que las variables se alojan en memoria (RAM, por lo general)
Si, pero para realizar la mayoria de instrucciones, por ejemplo Suma,Resta,Division,etc... el procesador utiliza los llamados Registros, que son una especie de memoria interna del procesador que usa para casi todas las operaciones.
Asi, segun el modo en que opere, esos registros pueden tener un tamaño máximo de 16,32,64 bits. Tambien  para ciertas instrucciones usa dos registros combinados duplicando el tamaño.
Citar
ero no entiendo que tiene que ver que el SO utilice software de 32 o 64 bits
Tene en cuenta que una aplicacion que utilice instucciones de 64bits no pude correr sobre un procesador de 32bit. Al reves generalmente se puede.

Karman

  • Miembro activo
  • **
  • Mensajes: 84
    • Ver Perfil
    • http://www.inexinferis.com.ar
Re: Cuidao Con Los Punteros
« Respuesta #11 en: Viernes 26 de Octubre de 2007, 06:14 »
0
Para que entiendas el tema del tamaño de un puntero, un puntero es una variable (un espacio de memoria) que contiene la dirección de otra variable o (en su defecto) de ninguna, te pongo un ejemplo simple:

char a='A';

Dependiendo de la máquina y del modelo de memoria que se utilice tenes las siguientes posibilidades:

Código: Text
  1.  
  2.  16bits               32bits                         64bits
  3. [00|56]       [00|00|00|56]    [00|00|00|00|00|00|00|56]
  4.  
  5.  

donde 56 = 'A' (no recuerdo si era ese valor... pero es un valor parecido si no), como ves, se desperdician varios bytes de memoria... pero eso es otro tema...
la cosa es que nuestra famosa variable a se puede encontrar en la posición de memoria:

Código: Text
  1.  
  2.  16bits               32bits                         64bits
  3. [23df]           [45ab87cd]            [53463bfade4525fe]
  4.  
  5.  

entonces:

char *p;

debe ser capaz de almacenar dicha dirección, es por esto que p, será de 16, 32, 64, 128 o el modelo de memoria que se utilice...

S2

ichigo15

  • Miembro activo
  • **
  • Mensajes: 37
    • Ver Perfil
Re: Cuidao Con Los Punteros
« Respuesta #12 en: Viernes 26 de Octubre de 2007, 08:55 »
0
Vale, ahora si que lo entiendo. Jue, que cacao tenía hasta ahora...
Bueno, gracias a todos por su ayuda.

Empiezo a pensar que no es que no sepa profesora de programación, si no que entendí mal cuando me explicó
[size=109]Nadie elige su nombre, te lo ponen cuando naces, pero sí su nick


No eres responsable de la cara que tienes, pero sí de la que pones
[/size]

Eternal Idol

  • Moderador
  • ******
  • Mensajes: 4696
  • Nacionalidad: ar
    • Ver Perfil
Re: Cuidao Con Los Punteros
« Respuesta #13 en: Viernes 26 de Octubre de 2007, 09:09 »
0
Cita de: "Karman"
char a='A';

Dependiendo de la máquina y del modelo de memoria que se utilice tenes las siguientes posibilidades:
¿Que plataformas conoces donde eso no ocupe un solo byte?

Nacional y Popular En mi país la bandera de Eva es inmortal.


Queremos una Argentina socialmente justa, económicamente libre y  políticamente soberana.
¡Perón cumple, Evita dignifica!


La mano invisible del mercado me robo la billetera.

Karman

  • Miembro activo
  • **
  • Mensajes: 84
    • Ver Perfil
    • http://www.inexinferis.com.ar
Re: Cuidao Con Los Punteros
« Respuesta #14 en: Viernes 26 de Octubre de 2007, 15:09 »
0
La verdad en todas las plataformas que trabajé vi eso, fijate:

Código: Text
  1.  
  2.   char a,b,c;
  3.   a='A';
  4.   printf("hola %c",a);
  5.   b=a-1;
  6.   printf("chau %c",b);
  7.   c=a+b;
  8.   printf("%c",c);
  9.   return (int)b;
  10.  
  11.  


:004012FF BA41000000               mov edx, 00000041
:00401304 89542404                mov dword ptr [esp+04], edx

:00401308 E863050000              Call 00401870 (* Reference To: msvcrt.printf, Ord:027Fh)
:0040130D C7042408304000          mov dword ptr [esp], 00403008
:00401314 B840000000              mov eax, 00000040
:00401319 89442404                mov dword ptr [esp+04], eax

:0040131D E84E050000              Call 00401870 (* Reference To: msvcrt.printf, Ord:027Fh
)
:00401322 C7042481FFFFFF          mov dword ptr [esp], FFFFFF81

:00401329 E832050000              Call 00401860 (* Reference To: msvcrt.putchar, Ord:0281h)
:0040132E C9                      leave
:0040132F B840000000              mov eax, 00000040
:00401334 C3                      ret

es por eso que en muchos manuales te dicen que es recomendable usar solo variables int ya que de todas formas siempre utilizas 32 bits...

S2

PD: Y en el mejor de los casos, con instrucciones como:

mov byte ptr [edx], 41

el registro edx termina conteniendo: 0x00000041

Eternal Idol

  • Moderador
  • ******
  • Mensajes: 4696
  • Nacionalidad: ar
    • Ver Perfil
Re: Cuidao Con Los Punteros
« Respuesta #15 en: Viernes 26 de Octubre de 2007, 15:33 »
0
Cita de: "Karman"
La verdad en todas las plataformas que trabajé vi eso, fijate:

Pero esas son variables en la pila, es tema del compilador, si haces esto:

Código: Text
  1.  
  2. #include <stdio.h>
  3.  
  4. char a = 'A';
  5. char c = 'B';
  6.  
  7. void main()
  8. {
  9.   char *ptr = &a;
  10.   printf("0x%X\r\n", ptr);
  11.   ptr = &c;
  12.   printf("0x%X\r\n", ptr);
  13. }
  14.  
  15.  

A y B son consecutivos y no hay ningun cero tras cada caracter, logico. Si usas memoria dinamica la misma historia.

Ademas si lo que decis fuera cierto cadena de caracteres ocuparia 4 * caracter y eso no es asi ...

Cita de: "Karman"
es por eso que en muchos manuales te dicen que es recomendable usar solo variables int ya que de todas formas siempre utilizas 32 bits...

Me parece que estas confundiendo con el tema de "alineamiento" a 32 bits.

Cita de: "Karman"
PD: Y en el mejor de los casos, con instrucciones como:

mov byte ptr [edx], 41

el registro edx termina conteniendo: 0x00000041

Con esa instruccion el valor de edx no se modifica en lo mas minimo, se cambia UNICAMENTE el primer byte (char digamos entonces) de la direccion que contiene edx. Eso es igual a hacer: *var = 'A';

mov edx, 0x41 si tendria el efecto que comentas.

Nacional y Popular En mi país la bandera de Eva es inmortal.


Queremos una Argentina socialmente justa, económicamente libre y  políticamente soberana.
¡Perón cumple, Evita dignifica!


La mano invisible del mercado me robo la billetera.

Karman

  • Miembro activo
  • **
  • Mensajes: 84
    • Ver Perfil
    • http://www.inexinferis.com.ar
Re: Cuidao Con Los Punteros
« Respuesta #16 en: Sábado 27 de Octubre de 2007, 07:39 »
0
Citar
Ademas si lo que decis fuera cierto cadena de caracteres ocuparia 4 * caracter y eso no es asi ...

no... no dije que si tuviera una cadena cada elemento ocuparía un byte... ya que las cadenas se agrupan en bytes consecutivos y el procesador mediante el índice (byte) puede ir pasando de caracter a caracter....

Citar
QUOTE (Karman @ Octubre 26, 2007 03:09 pm)

es por eso que en muchos manuales te dicen que es recomendable usar solo variables int ya que de todas formas siempre utilizas 32 bits...


Me parece que estas confundiendo con el tema de "alineamiento" a 32 bits.

no... lo que yo digo es para definir variables comunes, como contadores, etc... no para el trabajo con strings... y recomendaban justamente eso por lo que te mostré en el código en assembler...

S2

Eternal Idol

  • Moderador
  • ******
  • Mensajes: 4696
  • Nacionalidad: ar
    • Ver Perfil
Re: Cuidao Con Los Punteros
« Respuesta #17 en: Sábado 27 de Octubre de 2007, 10:21 »
0
Cita de: "Karman"
no... no dije que si tuviera una cadena cada elemento ocuparía un byte... ya que las cadenas se agrupan en bytes consecutivos y el procesador mediante el índice (byte) puede ir pasando de caracter a caracter....

Bueno, igual no es asi ... simplemente proba el codigo que deje, esos dos caracteres separados tienen direcciones consecutivas al no estar en la pila. No es una cuestion de tipo de datos ... por algo sizeof de un char devuelve uno y el compilador es capaz de leer y escribir ese caracter sin problemas, ocupe lo que ocupe por el alineamiento. Otro ejemplo interesante que esta bastante relacionado es este:

Código: Text
  1.  
  2. typedef struct _ejemplo
  3. {
  4.   char letra;
  5. }ejemplo;
  6.  
  7.  

¿Cual es el tamaño de esa estructura? Con el VC++ independientemente del packing alignment (P.A.) siempre sizeof es 1.

Vamos a otra:
Código: Text
  1.  
  2. typedef struct _ejemplo
  3. {
  4.   char letra;
  5.   int numero;
  6. }ejemplo;
  7.  
  8.  

Con el P.A. por defecto y con el packing a 4 esa estructura ocupa 8 bytes. ¿Que pasa con un P.A. de 1? Ocupa 5 bytes.

Packing alignment:
#pragma pack (show)
#pragma pack (1)
#pragma pack (show)

Un char es un BYTE, incluso cuando esta en la pila ocupando 4 bytes sizeof devuelve 1 y permite trabajar con ese byte unicamente (al menos directamente). Y si ocupa 4 bytes en la pila es por el funcionamiento de la misma:

push 1 = 0x6A 0x1
¿Que pasa con la pila? esp -= 4; o sub esp, 4

Cita de: "Karman"
no... lo que yo digo es para definir variables comunes, como contadores, etc... no para el trabajo con strings... y recomendaban justamente eso por lo que te mostré en el código en assembler...

Es assembly y tiene sentido usar DWORD a veces por dos razones: el alineamiento a 32 bits y el uso de la pila.

Por cierto ahora que lo veo con el tipo de retorno hiciste trampa:

Código: Text
  1.  
  2. char x()
  3. {
  4.      return 25;
  5. }
  6.  
  7.  

?x@@YADXZ (char __cdecl x(void)):
  00000000: 55                 push        ebp
  00000001: 8B EC              mov         ebp,esp
 00000003: B0 19              mov         al,19h
  00000005: 5D                 pop         ebp
  00000006: C3                 ret

Nacional y Popular En mi país la bandera de Eva es inmortal.


Queremos una Argentina socialmente justa, económicamente libre y  políticamente soberana.
¡Perón cumple, Evita dignifica!


La mano invisible del mercado me robo la billetera.

Karman

  • Miembro activo
  • **
  • Mensajes: 84
    • Ver Perfil
    • http://www.inexinferis.com.ar
Re: Cuidao Con Los Punteros
« Respuesta #18 en: Sábado 27 de Octubre de 2007, 19:02 »
0
Código: Text
  1.  
  2. Por cierto ahora que lo veo con el tipo de retorno hiciste trampa:
  3.  
  4.  

No hice trampa...  "Main() must return int"...

S2

Eternal Idol

  • Moderador
  • ******
  • Mensajes: 4696
  • Nacionalidad: ar
    • Ver Perfil
Re: Cuidao Con Los Punteros
« Respuesta #19 en: Sábado 27 de Octubre de 2007, 19:21 »
0
Cita de: "Karman"
No hice trampa...  "Main() must return int"...
Estaba en cursiva  ;) Y al fin y al cabo era engañoso, usaba el registro eax por ser int el tipo de retorno (que forzabas mediante casting).

Nacional y Popular En mi país la bandera de Eva es inmortal.


Queremos una Argentina socialmente justa, económicamente libre y  políticamente soberana.
¡Perón cumple, Evita dignifica!


La mano invisible del mercado me robo la billetera.

carmamezo

  • Miembro MUY activo
  • ***
  • Mensajes: 232
    • Ver Perfil
Re: Cuidao Con Los Punteros
« Respuesta #20 en: Domingo 28 de Octubre de 2007, 20:16 »
0
Resumiendo...

Los punteros no son más que contenedores de direcciones de memoria, la memoria puede ser más o menos grande dependiendo del sistema...
así en un procesador de 32 bits se pueden direccionar 2^32 direcciones y en uno de 64 2^64... por tanto un puntero ocupará 32 o 64 bits dependiendo de la arquitectura de la CPU.
Si te fijas con los procesadores de 32 bits no se podía poner más de 4GB de memoria RAM en el equipo, no es una limitación de la placa base o de la RAM es una limitación de la arquitectura de la CPU que permitía direccionar 2^32 direcciones de un byte.

La diferencia entre un puntero a char o a int no es el tamaño que ocupan pues ambos ocupan lo mismo sino la "profundidad" en bytes a la que apuntan... Así un puntero a char apunta un byte más la dirección inicial, y uno a int apunta 4 bytes más la dirección inicial (suponiendo 32 bits)...   Puedes probarlo de la siguiente manera:

Código: Text
  1. int *pa;
  2. char *pb;
  3. int dim;
  4.  
  5. dim = sizeof(pa);
  6. dim = sizeof(pb);
  7.  
Verás como dim es igual en ambos casos...

Ahora bien, si haces lo siguiente:
Código: Text
  1. int *pa,a=10;
  2. char *pb,b='c';
  3. int dim;
  4.  
  5. pa=&a;
  6. pb=&b
  7. dim = sizeof(*pa);
  8. dim = sizeof(*pb);
  9.  
Verás que en este caso dim en el primer caso vale 4 (en caso de 32 bits) y 1 en el segundo caso.

Un saludo.

 :lightsabre:
No hay tonto más molesto que el ingenioso.