{"id":221,"date":"2008-01-04T02:32:38","date_gmt":"2008-01-04T08:32:38","guid":{"rendered":"http:\/\/www.lastdragon.net\/?p=221"},"modified":"2008-01-04T02:37:17","modified_gmt":"2008-01-04T08:37:17","slug":"reservado-6","status":"publish","type":"post","link":"https:\/\/www.lastdragon.net\/?p=221","title":{"rendered":"Punteros en C y Linux lo que no hay que hacer con ellos"},"content":{"rendered":"<p>Me han mandado un E-mail con una pregunta interesante pidi\u00e9ndome un ejemplo pr\u00e1ctico del problema de los punteros.<\/p>\n<p>Me dicen que no entiende porque siempre lee en todos los manuales de C lo \u00fatil y peligroso de los punteros, cuando solo los manejan como una variable mas.<\/p>\n<p>Bueno ya que ando en mi rato de escribir sobre programaci\u00f3n, responder con un ejemplo practico como se me ha solicitado, no sin antes tirar mi rollo acerca del problema =)<\/p>\n<p>Los te\u00f3ricamente son variables sin tipo, porque un puntero tendra el tipo de la zona de memoria a la que apunta, como su nombre en ingles dice pointer o puntero, este tipo de variable es eso, un apuntador y a punta a donde sea<\/p>\n<p>Su utilidad radica en que podemos accesar por medio de ellos a zonas de memoria donde de otra forma no podr\u00edamos, su punto d\u00e9bil es que en tiempo de ejecuci\u00f3n C no comprueba los punteros esto es simples, no tiene porque y luego C es un lenguaje nivel medio, con menos ganas tiene porque.<\/p>\n<p>Sin embargo podemos confiar en el sistema operativo en que no permitir\u00e1 que un mal puntero uno dejado por ah\u00ed por un programador termine modificando valores de otros programas, al menos podemos confiar en GNU\/Linux y otros tipos de Unix =), claro que es una mala pr\u00e1ctica de programaci\u00f3n dejar punteros sueltos por ah\u00ed. En el mejor de los casos modificaremos valores de memoria de nuestro programa y causaremos que falle.<\/p>\n<p>Lo peor que puede pasarnos en un programa de producci\u00f3n, es que nuestro puntero apunte a una zona de memoria de nuestro programa y modifique cosas que no debe, si lo hace el programa no fallara, deber\u00eda, pero no lo har\u00e1, deber\u00eda darnos un fallo de segmento pero en lugar de eso como apunta a una zona de memoria en la que tiene \u201cpermiso\u201d continuara ejecut\u00e1ndose pero con informaci\u00f3n poco confiable y es esto el riesgo de los punteros, el programa no falla pero ya no puedes confiar en lo que el programa procesa y peor a\u00fan, al no existir un fallo palpable depurar un programa con un mal puntero se vuelve una tarea tit\u00e1nica, mas si el programa de mas cientos de l\u00edneas de c\u00f3digo.<br \/>\nAhora que hare para comprobar esto, deliberadamente escribir\u00e9 un programa que manipule un puntero que no retendr\u00e1 los valores en la memoria ram.<\/p>\n<p>\u00bfPor qu\u00e9 fallara y por que casi nadie se mete en l\u00edos con los punteros?<\/p>\n<p>No se meten en l\u00edos por suerte, porque muchas personas usan los punteros en variables que no caducan en todo el programa o el puntero caduca junto con la variable eliminando el riesgo.<\/p>\n<p>Nuestro programa fallara porque voy a apuntar a una zona \u201cvol\u00e1til\u201d y como lo hare.<\/p>\n<p>Bueno no es un secreto que cada que un programa llama una funci\u00f3n a ejecutarse, esta reserva la memoria para que se ejecute adem\u00e1s reserva la memoria para las variables locales de dicha funci\u00f3n y al terminar de ejecutarse antes de continuar la ejecuci\u00f3n de un programa se libera toda la memoria ocupada y se destruyen las variables o lo que es igual se liberan los segmentos de variables ocupadas por la funci\u00f3n y quedan a disposici\u00f3n de nuevas funciones y nuevas variables<\/p>\n<p>El programa que har\u00e1 lo siguiente.<\/p>\n<p>Un puntero global o que se mantendr\u00e1 vivo durante toda la ejecuci\u00f3n del programa sera llamado dentro de una funci\u00f3n y se le asignara la direcci\u00f3n de memoria de una variable dentro de esa funci\u00f3n, al terminar de ejecutarse la funci\u00f3n como dije anteriormente los datos ser\u00e1n destruidos pero nuestro puntero seguir\u00e1 vivo a apuntando a una variable \u201cmuerta\u201d, esto es una mala pr\u00e1ctica de programaci\u00f3n con punteros.<\/p>\n<p>El programa accesara inmediatamente a la zona muerta y leera el valor de dicha zona si este no ha sido modificado aunque la variable este muerta quedara el valor residual y podremos leerlo, despu\u00e9s de eso, deliberadamente lanzare una funci\u00f3n para fines practicos un sleep, esta reciclara la memoria y cuando intentemos leer la zona\u2026 ZAS los datos o est\u00e1n corruptos o no est\u00e1n.<\/p>\n<p>Luego le hare una asignaci\u00f3n manual de un valor y este se escribir\u00e1 en esa zona de memoria por que nuestro apuntador apunta ah\u00ed, si existir\u00eda alg\u00fan dato importante de otra variable ah\u00ed, seria destruido y luego consultare el valor, hay que recordar que esa zona se considera libre y puede ser usada en cualquier momento por otra funci\u00f3n, entonces, lanzare otra funci\u00f3n , otro sleep que volver\u00e1 a usarla y a pisotear lo que hab\u00eda almacenado ah\u00ed.<\/p>\n<p>Para fines practico nada de lo que almaceno en esa zona esta seguro de no ser destruido peor aun, nada en esa zona esta seguro por que igual  por medio del puntero puedo destruir la informaci\u00f3n de otra funci\u00f3n que en ese momento este en esa zona de memoria causando que el programa haga cosas raras.<\/p>\n<p>El c\u00f3digo <\/p>\n<p>#include &lt;stdio.h&gt;<\/p>\n<p>int *puntero = NULL;<br \/>\nint mem = 0;<\/p>\n<p>int funcion1()<br \/>\n{<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int entero = 100;<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mem = &amp;entero;<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf (&#8220;Direccion local %p<br \/>\nalmacenada %p\\n&#8221;,&amp;entero,mem);<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;<br \/>\n}<\/p>\n<p>\nint main ()<br \/>\n{<br \/>\nfuncion1 ();<\/p>\n<p>puntero = mem;<br \/>\nprintf (&#8220;Valor en el Puntero %d en %p\\n&#8221;,*puntero,mem);<\/p>\n<p>sleep (2);<\/p>\n<p>printf (&#8220;Valor en el Puntero %d en %p\\n&#8221;,*puntero,mem);<\/p>\n<p>*puntero = 10;<\/p>\n<p>printf (&#8220;Valor en el Puntero %d en %p\\n&#8221;,*puntero,mem);<\/p>\n<p>sleep (2);<\/p>\n<p>printf (&#8220;Valor en el Puntero %d en %p\\n&#8221;,*puntero,mem);<\/p>\n<p>return 0;<br \/>\n}<\/p>\n<p>Ojo, aunque confi\u00f3 en la protecci\u00f3n de memoria de Linux, nunca ejecutes este c\u00f3digo como root que aunque se ve tan inofensivo, y no deber\u00eda pasar nada malo al final el programa no se sale de su propia asignaci\u00f3n de ram, sin embargo no hay que abusar de la suerte y terminemos con un programa inestable y con acceso root, eso s\u00ed es malo, muy malo para nuestro GNU\/Linux<\/p>\n<p>El video de la pr\u00e1ctica.<\/p>\n<p><object width=\"425\" height=\"350\"><param name=\"movie\" value=\"http:\/\/www.youtube.com\/v\/AgI2uMr4Xos\"><\/param><embed src=\"http:\/\/www.youtube.com\/v\/AgI2uMr4Xos\" type=\"application\/x-shockwave-flash\" width=\"425\" height=\"350\"><\/embed><\/object><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Me han mandado un E-mail con una pregunta interesante pidi\u00e9ndome un ejemplo pr\u00e1ctico del problema de los punteros. Me dicen que no entiende porque siempre lee en todos los manuales de C lo \u00fatil y peligroso de los punteros, cuando solo los manejan como una variable mas. Bueno ya que ando en mi rato de&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[],"class_list":["post-221","post","type-post","status-publish","format-standard","hentry","category-programacion"],"_links":{"self":[{"href":"https:\/\/www.lastdragon.net\/index.php?rest_route=\/wp\/v2\/posts\/221","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.lastdragon.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.lastdragon.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.lastdragon.net\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.lastdragon.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=221"}],"version-history":[{"count":0,"href":"https:\/\/www.lastdragon.net\/index.php?rest_route=\/wp\/v2\/posts\/221\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.lastdragon.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=221"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.lastdragon.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=221"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.lastdragon.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=221"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}