C/Visual C - por q se explota un programa

 
Vista:

por q se explota un programa

Publicado por claudia liliana (5 intervenciones) el 17/09/2006 22:30:53
hola necesito saber porq motivo se puede explotar un programa en c++ despues de q se a comprobado q este sirve es decir se ejecuta y funciona y despues se vuelve a ejecutar y se esplota el programa maneja archivos y punteros
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

RE:por q se explota un programa

Publicado por fernando.gomez (1603 intervenciones) el 18/09/2006 03:23:42
Hola. Bueno, eso de que el programa "explota"... supongo que te refieres a que el programa deja de funcionar.

Bien, estas situaciones las podemos clasificar en dos partes. Primera, por factores internos; segunda, por factores externos. Esta última clasificación se refiere a que el programa asume ciertas condiciones, como hardware, sistema operativo, sistema de archivos, librerías y dependencias binarias, etcétera. Un ejemplo -rudimentario- es el siguiente. Supongamos que el sistema asume la existencia de una red. Y por tanto, hace uso sin empacho de alguna API, digamos, WinInet. Si asumimos que la red deba estar instalada, entonces una llamada a InternetOpenConnection jamás de los jamaces debería fallar. Y por ende, no verificamos el HANDLE que dicha función devuelve. Este tipo de omisiones son frecuentes. Al correr este programa donde el ambiente externo no cumple con los requisitos -explícitos o implícitos- del programa, éste "explota" sin previo aviso. Por supuesto, mi ejemplo es muy rudimentario, pero espero sirva para explicar mi punto.

Los factores internos usualmente se deben a una mala programación, en donde el programa cae en el lado oscuro de C++: el comportamiento indefinido. Tomemos por ejemplo el siguiente código:

char* sz = _T("Hola");
strcpy(sz, _T("Hola mundo");

Aquí se está generando -evidentemente- un comportamiento indefinido, porque estoy inicializando un puntero a caracter, que apunta a una dirección de memoria que contiene cinco caracteres -nulo incluído- __constantes__. El pretender modificar -vía strcpy- este bloque de memoria causa un comportamiento indefinido ya que ese bloque de memoria es constante y se pretende modificar. Puede que en algunos casos, ese bloque de memoria -aunque en teoría constante- no haya sido escrito como tal, sino en un búfer modificable. En esos casos -así es el comportamiento indefinido- funcionará, pero en el momento en que eso se escriba en un bloque de memoria constante, te va a "explotar" el programa.

Por si fuera poco, no solo se pretende cambiar una cadena de texto constante, sino que además se pretende meter más caracteres que los cinco asignados inicialmente. En estos casos el asunto es todavía peor. Si el bloque de memoria adjunto no está inicializado, el programa probablemente lanzará una excepción y se cerrará -en el mejor de los casos. En el peor, puede que haya un bloque de memoria válido y éste se modifique, y pues ahí ya estarías afectando a otra variable. Si esta variable es una creada por tu código, su valor simplemente estará mal; si es una variable que pertenece a alguna rutina del sistema operativo -handles de ventanas o peor aún, drivers- puede que en realidad hagas explotar tu computadora.

Hay otro caso: muchos compiladores -VC incluído- cuando trabajan en modo de "debug", inicializan el bloque de memoria correspondiente a una variable en particular, y además de los bytes que están a sus alrededores (esto lo hacen por si tienes el ejemplo anterior, mientras haces tus pruebas, no llegues a fastidiar memoria asignada a recursos del sistema. En estos casos, tendrías el escenario donde el programa funciona en modo de debug... pero falla en modo de release.

Finalmente, a guisa de anécdota, te comento que en una ocasión me heredaron un programa el cuál funcionaba perfectamente en "release", pero lanzaba ASSERTs de MFC en modo de debug. Esto era consecuencia precísamente de lo que te comenté en el párrafo anterior. MFC, con su clase CString, evita muchos de estos errores, pero lanza ASSERTs. Tuve que aprender a base de golpes y largas desveladas que el problema era éste, debido al manejo de cadenas ASCII y Unicode indiscriminadamente, mezcladas a cada rato. Mi sugerencia: revisa el código y asegúrate a cada paso de que sigue sin problemas el estándar, o al menos, la documentación de tu compilador.

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