Ejercicio 4 - Practico 0

Ejercicio 4 - Practico 0

de Joel Cabrera Dechia -
Número de respuestas: 5

Buenas,

Haciendo este ejercicio me surgieron algunas preguntas.

Después de varios intentos consigo el siguiente fragmento para pedir la frase:

printf("Ingrese una frase: ");
char *frase = new char;
scanf("%[^\n]s",frase);

No comprendo del todo qué es lo que pasa "internamente".
Lo que yo entiendo es que se crea un puntero a char y además se le pide memoria con el new. Ahora, esa memoria que se pide, tiene el tamaño como para almacenar un caracter, ¿o no?
En el caso de que así sea, ¿por qué al ejecutar scanf toma correctamente toda la frase hasta leer el salto de línea si teóricamente yo había pedido espacio por un solo caracter?
Además luego puedo acceder a cada caracter como si fuera un arreglo (en este caso frase[natural]), ¿se debe al %s?

Desde ya les agradezco el tiempo.

Saludos, 
Joel


En respuesta a Joel Cabrera Dechia

Re: Ejercicio 4 - Practico 0

de Ignacio Facello Marcotte -
Porque el programa tiene asignada un área de memoria, y te va dando memoria para tus variables a medida que pedís. El puntero no sabe de qué tamaño es el área de memoria que le asignaste. Sólo sabe que apunta a un lugar específico. scanf lee y guarda en ese lugar, y sigue escribiendo. Si después de eso tuvieras otra variable, la estarías sobreescribiendo. funciona todo porque la memoria que estás sobreescribiendo no la usás para nada más.
En respuesta a Ignacio Facello Marcotte

Re: Ejercicio 4 - Practico 0

de Joel Cabrera Dechia -
Gracias Ignacio por tu respuesta y por tormarte el tiempo.
Sigo sin entender la idea; comparto mi razonamiento y a ver si se ve mi error.
Yo lo que veo es que al hacer new char estoy pidiendo memoria para una variable de tipo char, el puntero apunta a una variable de tipo char. Una frase es en realidad un arreglo de caracteres, o sea varios caracteres, no solo uno. Ahí es donde no entiendo por qué no debería hacer new para cada caracter que lee scanf.
Quizás el error esta desde el principio de mi planteo y me estoy confundiendo, pero no logro entenderlo.

Saludos
En respuesta a Joel Cabrera Dechia

Re: Ejercicio 4 - Practico 0

de Ignacio Facello Marcotte -
scanf no pide memoria, scanf escribe donde vos le dijiste que escriba.

Voy a meter una explicación medio larga, pero primero, lo que falta: si querés reservar cien caracteres hacé:
char *frase = new char[100];

Imaginate que esta es la memoria:
[00][00][00][00][00][00][00][00][00][00]

Tenés sólo diez bytes, digamos que es una computadora muy chica. Pero bueno. En principio toda esa memoria está libre, y la tenés toda marcada como no asignada. Ahora, vos hacés:

char *frase = new char;

Vamos a ignorar por ahora dónde se guarda el valor del puntero. Vos con new le dijiste a la computadora "asigname espacio para guardar un char", y entonces la computadora te dice "ok, acá tenés, está en esta dirección de memoria", y marca espacio para un char (un byte) como usado.

[00][00][00][00][00][00][00][00][00][00]
^-- este byte está marcado como usado ^--- de acá en adelante está marcado libre

Ok, ahora digamos que llamás a scanf, y le pasásfrase. Le estás diciendo: escribí en este lugar lo que entre el usuario. El usuario escribe hola, chars 'h', 'o', 'l', 'a', y un 0 al final para marcar que se terminó. Pasando esos chars a hexadecimal tenés en memoria esto ahora:

  h   o   l   a  \0
[68][6F][6L][61][00][00][00][00][00][00]
^-- este byte está marcado como usado ^--- de acá en adelante está marcado libre

Pero fijate, a partir del segundo byte sigue marcado como libre. Supongamos que ahora hacés lo mismo, y decís char *frase2 = new char. Le pediste a la computadora más memoria, suficiente para un char. La computadora dice "ok, acá tenés, y te da un puntero al primer espacio libre de memoria, y lo marca usado. Y ahora agarrás y llamás a scanf y le pasás frase2 para que escriba. Y el usuario ingresa "pepe", y scanf escribe a partir del segundo espacio.

[68][70][65][70][65][00][00][00][00][00]

Ves ahí lo que pasó?

[68][70][65][70][65][00][00][00][00][00]
^- frase apunta acá
^- frase2 apunta acá

Y ahora si agarrás y le decís que haga un printf de lo que hay en frase, va a ir a esa dirección de memoria, y leer caracteres hasta encontrar un cero. ¿Y qué va a escribir? Va a escribir "hpepe". Que definitivamente no es lo que querés.

En respuesta a Ignacio Facello Marcotte

Re: Ejercicio 4 - Practico 0

de Favio Rafael Cardoso Sanchez -
Hola, me surgió una duda sobre esto, de que manera podría hacer lo mismo pero con el detalle de que se actualice la posición de libre en la memoria?, es decir un arreglo dinámico como este pero que no sea posible sobre escribirlo con mas información por error.
Gracias!