Herramientas de usuario

Herramientas del sitio


punteros

Diferencias

Muestra las diferencias entre dos versiones de la página.

Enlace a la vista de comparación

Ambos lados, revisión anteriorRevisión previa
Próxima revisión
Revisión previa
punteros [2014/08/12 11:04] – [Variables dinámicas: malloc/free] lmateupunteros [2021/09/22 17:07] (actual) – [Big endian vs. Little endian] lmateu
Línea 110: Línea 110:
 int main() { int main() {
   int a= 1, b= 2;   int a= 1, b= 2;
-  int *px= &a, *py= &b;+  int *pa= &a, *pb= &b;
   swap_ptr(&pa, &pb);   swap_ptr(&pa, &pb);
 } }
 </code> </code>
  
-Ahora se busca que después de invocar swap_ptr, //px// apunte a //b// y //py// apunte a //a// ¿Como habría que definir swap_ptr?  Ahora se necesita que los parámetros de swap_ptr sean punteros a punteros.  Esto se hace empleando 2 asteriscos en la declaración:+Ahora se busca que después de invocar swap_ptr, //pa// apunte a //b// y //pb// apunte a //a// ¿Como habría que definir swap_ptr?  Ahora se necesita que los parámetros de swap_ptr sean punteros a punteros.  Esto se hace empleando 2 asteriscos en la declaración:
  
 <code> <code>
Línea 290: Línea 290:
 </code> </code>
  
-¿De que sirve pedir espacio para 10 enteros consecutivos en la memoria?  Porque a partir del puntero p es posible acceder a todos estos enteros.  La expresión //p+i//, en donde i es un entero entre 0 y 9, apunta al i-ésimo de los enteros.  Por lo tanto la expressión //*(p+i)// representa la i-ésima variable creada.  La siguiente figura ilustra el concepto:+¿De qué sirve pedir espacio para 10 enteros consecutivos en la memoria?  Porque a partir del puntero p es posible acceder a todos estos enteros.  La expresión //p+i//, en donde i es un entero entre 0 y 9, apunta al i-ésimo de los enteros.  Por lo tanto la expressión //*(p+i)// representa la i-ésima variable creada.  La siguiente figura ilustra el concepto:
  
 {{ :punteros_arreglos.png?nolink&600 |}} {{ :punteros_arreglos.png?nolink&600 |}}
Línea 344: Línea 344:
   ...   ...
   r=p;   r=p;
 +  ...
   free(p);   free(p);
 +  ...
   x= *r; /* r es dangling reference */   x= *r; /* r es dangling reference */
 </code> </code>
  
-Aquí r y p apuntan a la misma dirección de memoria.  Al liberar ese espacio con //free(p)// deja de ser legal acceder a ella por medio de //*p// y //también por medio de *r//.  Aquí el error es trivial de detectar pero en programas más complejos es muy frecuente que accidentalmente se accede a memoria ya liberada muy lejos del código en donde se invocó free y por lo tanto es un error difícil de diagnosticar.  Este error podría conducir a un //segmentation fault// o también conducir a resultados incorrectos.+Aquí r y p apuntan a la misma dirección de memoria.  Al liberar ese espacio con //free(p)// deja de ser legal acceder a ella por medio de //*p// y //también por medio de *r//.  Aquí el error es trivial de detectar pero en programas más complejos es muy frecuente que accidentalmente se accede a memoria ya liberada muy lejos del código en donde se invocó free y por lo tanto es un error difícil de diagnosticar.  Este error podría conducir a un //segmentation fault// o también conducir a resultados incorrectos.  La herramienta comercial //purify// o la gratuita //valgrind// revisan que en la ejecución de un programa no ocurran este tipo de errores.  La desventaja es que el tiempo de ejecución se multiplica por 100.  Además a veces diagnostican errores inexistentes o peor aún, no detectan todos los errores.
  
 ==== Restricciones ==== ==== Restricciones ====
  
-Solo está permitido sumar o restar un entero a un puntero.  También está permitido restar 2 punteros del mismo tipo.  Pero no tiene sentido multiplicar o dividir un puntero por cualquier valor.  Tampoco tiene sentido sumar 2 punteros.  Por ejemplo si se tienen las siguientes declaraciónes:+Solo está permitido sumar o restar un entero a un puntero.  También está permitido restar 2 punteros del mismo tipo.  Pero no tiene sentido multiplicar o dividir un puntero por cualquier valor.  Tampoco tiene sentido sumar 2 punteros.  Por ejemplo si se tienen las siguientes declaraciones:
  
 <code> <code>
Línea 430: Línea 432:
 {{ :punteros_endianness.png?nolink&400 |}} {{ :punteros_endianness.png?nolink&400 |}}
  
-El valor retornado por esta función depende de una propiedad del hardware.  En los procesadores x86 los punteros apuntan al byte menos significado de un entero.  Esto se denomina una arquitectura //little endian//. Por lo tanto en este tipo de arquitecturas p[0] es 1 y la función de más arriba retorna 1 (o verdadero).  En cambio también existen arquitecturas que se denominan //big endian// en donde los punteros apuntan al byte más significativo de un entero.  La arqutectura Power de IBM es //big endian// así como los //mainframes// que todavía fabrica esta marca.  La arquitectura Sparc de Oracle también es //big endian//.+El valor retornado por esta función depende de una propiedad del hardware.  En los procesadores x86 los punteros apuntan al byte menos significado de un entero.  Esto se denomina una arquitectura //little endian//. Por lo tanto en este tipo de arquitecturas p[0] es 1 y la función de más arriba retorna 1 (o verdadero).  En cambio también existen arquitecturas que se denominan //big endian// en donde los punteros apuntan al byte más significativo de un entero.  La arquitectura Power de IBM es //big endian// así como los //mainframes// que todavía fabrica esta marca.  La arquitectura Sparc de Oracle también es //big endian//.
  
 Los únicos casos en donde esta distinción arquitectural es importante es cuando se graban archivos binarios o se transmiten datos binarios por la red.  Es decir en vez de escribir los enteros en formato ascii en notación decimal, se escriben directamente los 4 bytes del entero.  Si un archivo binario es escrito en una arquitectura little endian pero leído en una arquitectura big endian, los números leídos serán incorrectos. Los únicos casos en donde esta distinción arquitectural es importante es cuando se graban archivos binarios o se transmiten datos binarios por la red.  Es decir en vez de escribir los enteros en formato ascii en notación decimal, se escriben directamente los 4 bytes del entero.  Si un archivo binario es escrito en una arquitectura little endian pero leído en una arquitectura big endian, los números leídos serán incorrectos.
punteros.1407852277.txt.gz · Última modificación: 2014/08/12 11:04 (editor externo)