Dev - C++ - Duda extraña con punteros

 
Vista:

Duda extraña con punteros

Publicado por Xromx (1 intervención) el 24/07/2014 14:54:05
Tengo una duda con punteros. Tengo el siguiente programa

1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
int main()
{
   int numero=4;
   int *ptr;
 
   ptr= &numero;
   std::cout  << ptr << std::endl;
 
 
   return 0;
}

Al ejecutarlo me devuelve por consola la dirección de memoria de la variable numero. De acuerdo.

Sin embargo si ejecuto lo siguiente:

1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
int main()
{
   char letra='X';
   char *ptr;
 
   ptr= &letra;
   std::cout  << ptr << std::endl;
 
 
   return 0;
}

Me devuelve un resultado "raro" del estilo X+3 caracteres raros más, en lugar de la dirección de memoria de la variable "letra"

Alguien sabe por qué pasa esto?

Gracias
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
Imágen de perfil de vangodp
Val: 73
Ha disminuido 1 puesto en Dev - C++ (en relación al último mes)
Gráfica de Dev - C++

Duda extraña con punteros

Publicado por vangodp (287 intervenciones) el 25/07/2014 02:59:14
La verdad es algo raro pero tengo una teoría.
Esto: char *ptr;
es lo mismo que esto:
char ptr[0];

O sea que es como una tabla sin definir el tamaño. apunta a la posicion 0 de la tabla.

La prueba esta aquí:
1
2
3
4
5
6
7
8
#include <iostream>
int main() {
    char letra = 'X';
    char *ptr = NULL;
    ptr = &letra;
    std::cout << ptr[0] << std::endl;
    return 0;
}
cuando imprimo std::cout << ptr[0] << std::endl; con ptr[0] que es la primera posición ¡¡tacha!!! esta tu X puesta ahí.
Es como si estuvieras creando una tabla de un solo valor pero es así de estúpido el tema XDD
1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
using namespace std;
 
int main() {
 
    char *ptr = "abc";
 
    std::cout << ptr[0] << ptr[1] << ptr[2];
 
    return 0;
}
En ese caso char *ptr apunta a la posicion 0(letra a) de la cadena "abc"

El por que te imprime así de raro es que no tengo ni idea, pero tenga presente que es como una tabla y el nombre de una tabla es muy similar a un puntero.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Duda extraña con punteros

Publicado por Capitan Kirk (48 intervenciones) el 25/07/2014 08:25:07
Aunque no sé si es el caso en C++, dado que deriva de C, supongo que lo que ocurre es que, en el fondo, C++ maneja los arrays de caracteres igual que C, es decir, esperando un carácter nulo como terminador de cadena. En tu caso, parece que lo que ocurre es que, cuando le dices que te imprima ptr (que es un puntero a char) lo que está haciendo es intentar imprimir la "cadena de caracteres" (entrecomillado porqte ptr no apunta al comienzo de una cadena de caracteres, sino a UN caracter) a la que apunta ptr, con lo que te va a mostrar la 'X' y, a continuación, todo lo que vaya encontrando en memoria hasta que topa con un 0 (carácter nulo). Aunque, repito, son suposiciones. Comprueba si hay algún especificador de formato para cout que te permita indicar que lo que quieres imprimir es el puntero a char en sí, no la "cadena de caracteres" a la que apunta.

Saludos,
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil

Duda extraña con punteros

Publicado por Pico (24 intervenciones) el 25/07/2014 15:51:28
Lo que está claro es que el compilador no trata igual un puntero a un int que uno a un char.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
std::cout << ptr << std::endl;
00415345  mov         esi,esp
00415347  mov         eax,dword ptr [MSVCP100D_NULL_THUNK_DATA (42D334h)]
0041534C  push        eax
0041534D  mov         edi,esp
0041534F  mov         ecx,dword ptr [ebp-18h]
00415352  push        ecx
00415353  mov         ecx,dword ptr [__imp_std::cout (42D324h)]
00415359  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (42D338h)]
0041535F  cmp         edi,esp
00415361  call        @ILT+430(__RTC_CheckEsp) (4111B3h)
00415366  mov         ecx,eax
00415368  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (42D33Ch)]
0041536E  cmp         esi,esp
00415370  call        @ILT+430(__RTC_CheckEsp) (4111B3h)
     std::cout << ptr2 << std::endl;
00415375  mov         esi,esp
00415377  mov         eax,dword ptr [MSVCP100D_NULL_THUNK_DATA (42D334h)]
0041537C  push        eax
0041537D  mov         ecx,dword ptr [ebp-30h]
00415380  push        ecx
00415381  mov         edx,dword ptr [__imp_std::cout (42D324h)]
00415387  push        edx
00415388  call        std::operator<<<std::char_traits<char> > (411320h)
0041538D  mov         ecx,eax
0041538F  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (42D33Ch)]
00415395  cmp         esi,esp
00415397  call        @ILT+430(__RTC_CheckEsp) (4111B3h)

El puntero a int se imprime en la dirección 00415359; el del char en 00415388.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil
Val: 338
Ha mantenido su posición en Dev - C++ (en relación al último mes)
Gráfica de Dev - C++

Duda extraña con punteros

Publicado por Martín (158 intervenciones) el 09/08/2014 04:51:55
La razón es que para std::cout el operador de inserción << está sobrecargado: son varias funciones distintas que se llaman igual (operator<<) pero que toman distintos argumentos.

Para el puntero a entero, el compilador utiliza:
1
ostream& operator<< (void* val);
que inserta la dirección de memoria donde está alojada la variable.

Para el puntero a carácter, el compilador utiliza:
1
ostream& operator<< (ostream& os, const char* s);
que inserta la cadena a carácter de estilo C, para la que espera un '\0' como terminador.

Para que std::cout muestre la dirección del char *ptr; se debe indicar el primero de los operadores, casteando el puntero a void*:
1
std::cout  << static_cast<void*>(ptr) << std::endl;

Si quieres revisar estos conceptos con algún detalle, puedes escribirme a mi dirección de mail.
(Ah, para consultorías dedicadas cobro 0,03 Bitcoin la hora :)
Saludos.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar