Foros del Web » Programación para mayores de 30 ;) » C/C++ »

Capacidad de los tipos

Estas en el tema de Capacidad de los tipos en el foro de C/C++ en Foros del Web. Hay algo en C++ acerca de la capacidad de almacenamiento de los tipos que no comprendo. Veamos, tengo este código: Código: #include<iostream> using namespace std; ...
  #1 (permalink)  
Antiguo 01/08/2007, 15:54
 
Fecha de Ingreso: diciembre-2005
Ubicación: Redondela (Galicia)
Mensajes: 368
Antigüedad: 19 años
Puntos: 1
Capacidad de los tipos

Hay algo en C++ acerca de la capacidad de almacenamiento de los tipos que no comprendo.

Veamos, tengo este código:

Código:
#include<iostream>
using namespace std;
int main(){
    short b;
    cin >> b;
    cout << b << endl;
    return 0;
}
Habiendo compilado el programa en una plataforma de 32 bits no debería poder meter un entero superior a 2147483647 ni inferior a -2147483648 sin producir resultados inesperados. Cierto

Otro:

Código:
#include<iostream>
using namespace std;
int main(){
    bool b;
    cin >> b;
    cout << b << endl;
    return 0;
}
En este sólo puedo meter los valores 0 o 1. Correcto

Pero he aquí mi problema:

Código:
#include<iostream>
using namespace std;
int main(){
    char b[5];
    cin >> b;
    cout << b << endl;
    return 0;
}
Se supone que ahí sólo podría almacenar una cadena de 4 carácteres (de hecho, si intento compilar algo como char b[5] = "qwert"; el compilador no me deja). Pero metiendo los carácteres con cin entran muchos más... ¿por qué?

¿Alguien podría explicármelo?

Concretamente, el error que recibo al pasarme mucho del supuesto espacio de la variable al introducir texto mediante cin es el siguiente:

Cita:
9597 [main] prueba 2684 _cygtls::handle_exceptions: Exception: STATUS_ILLEGAL
_INSTRUCTION
108254 [main] prueba 2684 open_stackdumpfile: Dumping stack trace to prueba.exe
.stackdump
347588 [main] prueba 2684 _cygtls::handle_exceptions: Exception: STATUS_ACCESS_
VIOLATION
463187 [main] prueba 2684 _cygtls::handle_exceptions: Error while dumping state
(probably corrupted stack)
Pero como dije, tengo que pasarme más de lo que yo me esperaba
  #2 (permalink)  
Antiguo 02/08/2007, 08:19
Avatar de _Lucifer_  
Fecha de Ingreso: junio-2006
Mensajes: 1.662
Antigüedad: 18 años, 7 meses
Puntos: 28
Re: Capacidad de los tipos

Las si vas a inicializar el arreglo de char al momento de la declaración debes hacerlo asi:

Código:
char b[] = "qwert";
//otra manera :
char *b = "qwert";
Cuando tratas de guardar una cadena de más de 5 caracteres en el ejemplo que pusiste:
Código:
#include<iostream>
using namespace std;
int main(){
    char b[5];
    cin >> b;
    cout << b << endl;
    return 0;
}
Estás escribiendo en una zona de memoria no reservada, es decir de b[5] en adelante, por eso te da un error de violación de segmento.

Para evitar esa clase de cosas el C++ te provee de una clase llamada string, que reserva más memoria a medida que la longitud de los caracteres que almacenas aumenta.

Saludos
__________________
Si crees que no tiene sentido, etonces probablemente lo tenga... :arriba:
  #3 (permalink)  
Antiguo 02/08/2007, 12:31
 
Fecha de Ingreso: diciembre-2005
Ubicación: Redondela (Galicia)
Mensajes: 368
Antigüedad: 19 años
Puntos: 1
Re: Capacidad de los tipos

Cita:
Estás escribiendo en una zona de memoria no reservada, es decir de b[5] en adelante, por eso te da un error de violación de segmento.
Eso lo se, pero mi duda no es acerca de eso, si no que querría saber el porqué de que la violación de segmento no se produzca ya con 5 o 6 caracteres (ya que b[5] sólo podría almacenar 4, según lo que yo creía y según lo que me indica el compilador), si no que puedo almacenar algunos más en el espacio que supuestamente hay reservado (en las pruebas que realicé la violación de segmento sólo se producía a partir de 28 carácteres... que es bastante más), al introducirlos mediante cin.
  #4 (permalink)  
Antiguo 02/08/2007, 12:43
Avatar de Eternal Idol  
Fecha de Ingreso: mayo-2004
Ubicación: Lucentum
Mensajes: 6.192
Antigüedad: 20 años, 7 meses
Puntos: 74
Re: Capacidad de los tipos

9597 [main] prueba 2684 _cygtls::handle_exceptions: Exception: STATUS_ILLEGAL_INSTRUCTION

Depura el programa, eso suena a que o bien sobreescribiste el codigo o lo que me parece mas factible jodiste la pila y entonces al hacer return volvio a cualquier lado.
__________________
¡Peron cumple, Evita dignifica! VIVA PERON CARAJO
  #5 (permalink)  
Antiguo 02/08/2007, 13:10
Avatar de _Lucifer_  
Fecha de Ingreso: junio-2006
Mensajes: 1.662
Antigüedad: 18 años, 7 meses
Puntos: 28
Re: Capacidad de los tipos

A mi me daba el error a partir del 5to o 6to caracter. Seguramente con una cadena tan larga sobreescibes alguna zona de memoria que no debes, como te dice Eternal Idol, tal vez sea la pila o algún segmento de código que no debiste tocar.

Saludos
__________________
Si crees que no tiene sentido, etonces probablemente lo tenga... :arriba:
  #6 (permalink)  
Antiguo 02/08/2007, 14:54
 
Fecha de Ingreso: diciembre-2005
Ubicación: Redondela (Galicia)
Mensajes: 368
Antigüedad: 19 años
Puntos: 1
Re: Capacidad de los tipos

El código es este:

Código:
#include<iostream>
using namespace std;
int main(){
    char b[5];
    cin >> b;
    cout << b << endl;
    return 0;
}
Cita:
A mi me daba el error a partir del 5to o 6to caracter
¡Eso es lo que yo suponía que pasaría! Pero el programa funciona correctamente hasta que paso de 27 caracteres... Es más, si cambio char b[5]; por char b[2];, puedo meter hasta 5 carácteres sin que se produzcan errores. Y con char b[3]; puedo almacenar hasta 27 (como con char b[5];, y no creo que sea una coincidencia)

Lo que me interesa saber no es el porqué del error, eso lo comprendo... escribo en un espacio que no era el mío (puede contener basura, nada o información de otros programas... etc). Lo que me interesa saber es el porqué de que el error se produzca con un número mayor de caracteres sobrantes de lo que es de esperar (sería de esperar que el error se produjese con un sólo carácter que se pasase del espacio...)
  #7 (permalink)  
Antiguo 02/08/2007, 15:36
Avatar de Eternal Idol  
Fecha de Ingreso: mayo-2004
Ubicación: Lucentum
Mensajes: 6.192
Antigüedad: 20 años, 7 meses
Puntos: 74
Re: Capacidad de los tipos

Cita:
Iniciado por Sanva Ver Mensaje
Lo que me interesa saber no es el porqué del error, eso lo comprendo... escribo en un espacio que no era el mío (puede contener basura, nada o información de otros programas... etc). Lo que me interesa saber es el porqué de que el error se produzca con un número mayor de caracteres sobrantes de lo que es de esperar (sería de esperar que el error se produjese con un sólo carácter que se pasase del espacio...)
¿Que es lo que hay despues? Eso depende de muchos factores y por lo tanto no siempre se ve el efecto negativo de inmediato.

El codigo ya lo pusiste antes: DEPURA EL PROGRAMA INSTRUCCION POR INSTRUCCION PARA SABER QUE PASA EXACTAMENTE (preferentemente en assembly).
__________________
¡Peron cumple, Evita dignifica! VIVA PERON CARAJO
  #8 (permalink)  
Antiguo 02/08/2007, 16:23
 
Fecha de Ingreso: diciembre-2005
Ubicación: Redondela (Galicia)
Mensajes: 368
Antigüedad: 19 años
Puntos: 1
Re: Capacidad de los tipos

Quizá debería haberlo comentado desde el principio: Mi nivel en C++ es básico... tan sólo estoy empezando con él, y no se cómo depurar (quizá puedas orientarme en ese sentido... ¿un pequeño ejemplo por tu parte, quizá?). Y tampoco conozco el lenguaje Ensamblador.

¿Quizá no debería entonces preocuparme de cosas a tan bajo nivel y continuar con mi aprendizaje? (Me gusta asentar muy bien mis conocimientos para no arrastrar errores a lo largo del proceso de aprendizaje de un lenguaje o una tecnología)
  #9 (permalink)  
Antiguo 03/08/2007, 00:00
Avatar de Eternal Idol  
Fecha de Ingreso: mayo-2004
Ubicación: Lucentum
Mensajes: 6.192
Antigüedad: 20 años, 7 meses
Puntos: 74
Re: Capacidad de los tipos

Cita:
Iniciado por Sanva Ver Mensaje
Quizá debería haberlo comentado desde el principio: Mi nivel en C++ es básico... tan sólo estoy empezando con él, y no se cómo depurar (quizá puedas orientarme en ese sentido... ¿un pequeño ejemplo por tu parte, quizá?). Y tampoco conozco el lenguaje Ensamblador.
En este caso me parece que seria una perdida de tiempo ya que sin saber assembly no lograrias comprender el motivo real del error. De cualquier manera yo uso WinDbg ... la logica de todo depurador es bastante simple, se puede ejecutar una instruccion a la vez y ver el estado de la memoria, los registros del microprocesador, la pila de llamadas, etc. Ademas de establecer puntos de ruptura, donde se detiene la ejecucion si estos son alcanzados.

Cita:
Iniciado por Sanva Ver Mensaje
¿Quizá no debería entonces preocuparme de cosas a tan bajo nivel y continuar con mi aprendizaje? (Me gusta asentar muy bien mis conocimientos para no arrastrar errores a lo largo del proceso de aprendizaje de un lenguaje o una tecnología)
Basicamente las variables locales estan en la pila, la pila en x86 tambien se usa para pasar parametros y contiene la direccion de retorno de las funciones. Ademas las paginas de memoria suelen ser de minimo 4096 bytes con lo cual generalmente no se produce una excepcion de acceso invalido al instante. Por lo que se ve en los mensajes que dejaste lo que pasa es que se jode la pila y terminas ejecutando un codigo incorrecto, pero sin depurarlo solo puedo conjeturar ... segui adelante, el punto con esto es C/C++ no te protegen en lo mas minimo de problemas de limites y los buffers overflows estan al acecho.
__________________
¡Peron cumple, Evita dignifica! VIVA PERON CARAJO
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 17:53.