Este documento describe la memoria en el lenguaje C. Explica que la memoria se divide en páginas y segmentos como el texto, datos y pila. También cubre la asignación dinámica de memoria mediante funciones como malloc que asignan memoria en el segmento de montón en tiempo de ejecución. Finalmente, enfatiza la importancia de entender cómo funciona la memoria para programar efectivamente en C.
2. Lenguaje C
Me falla la memoria
Cuando se programa en C como si fuera Visual Basic, Javascript o PHP (copiar y pegar
código de otros), llega un momento en que la cantidad de errores inexplicables por uso
de memoria superan el animo de continuar usándolo. Ese es el mejor momento de
detenerse a reflexionar realmente si uno quiere aprender a dominar el lenguaje y es ese
momento en el que se comienza a respetarlo (u odiarlo)
Naturalmente, el 99% de los casos serán por culpa de los punteros, sin embargo, y
detrás de los punteros, esta algo mas grande y complicado que el mismo lenguaje C, y se
trata de la memoria junto con los mecanismos que usa el Sistema Operativo de turno
para administrarla.
Un Administrador de red es más próximo a un Sistema Operativo que cualquier otro y
conoce bien las ventajas de la memoria. Entender como funciona y la relación íntima
que tiene con el Lenguaje C será el inicio para convertirse en root
>>Fids
5. Lenguaje C
Script III – Memoria en C
>> Pages
>> Memoria Virtual
>> Process Address Space
>> Memory Maps
>> Secciones de Programa
>> Librerías
>> Asignación Dinámica - Heap Segment
>> Asignación Dinámica - Malloc
>> Asignación Dinámica - Calloc
>> Asignación Dinámica - Realloc
>> Asignación Dinámica - Free
>> Asignación Dinámica - Memory Mappings
>> Asignación Dinámica - Stack Segment
>> Asignación Dinámica - Stack Based
>> Asignación Dinámica - Bonus Track
>> Otras Funciones de Memoria
>> Asignación Dinámica - Comparaciones
>> Recomendaciones y Reglas
6. Lenguaje C
PAGES
page page page page … … page page page page xGB0
4Kb (32bits)
8Kb (64bits)
En los sistemas operativos modernos, la Memoria es dividida en páginas (pages) que
vienen a ser la unidad básica de memoria utilizable por la MMU (Memory
Management Unit). Su tamaño usualmente es 4KB (para sistemas de 32bits) y 8KB
(para sistemas de 64bits)
¿Qué es la MMU?
La MMU es el hardware que se encarga de
administrar la memoria y realizar las
traducciones de direcciones virtuales a
direcciones físicas.
7. Lenguaje C
MEMORIA VIRTUAL
Todo programador debe tener en cuenta que, ahora, la memoria que utiliza es una
«ilusión» orquestada por el kernel. Hoy los sistemas operativos trabajan con
Memoria Virtual, un mecanismo por la cual se puede usar mas memoria de la que
hay en la RAM. Ahora la swap o un simple archivo puede guardar información como
si fuera una Memoria RAM.
Page
Page
Page
…
Page
Page
ram
swap
file
kernel
Virtual
Memory
8. Lenguaje C
MEMORIA VIRTUAL
Al ser un mecanismo virtual, el kernel se ocupa de tener un registro minucioso y
constante del estado de cada página de memoria. Sabe por ejemplo si una página esta
bloqueada, en disco ,en la swap, o si esta libre entre otras cosas. Para un programador,
el kernel ejecutará 2 tareas fundamentales: Asignar y Liberar memoria
Page
Page
Page
…
Page
Page
ram
swap
file
kernel
Virtual
Memory
In use
Free
Free
Locked
In use
9. Proceso N
Proceso 2
Lenguaje C
PROCESS ADDRESS SPACE
¿Cómo usará mi programa la Memoria Virtual?
Mediante las funciones exec, un programa es cargado en memoria (pasando a ser un
proceso). Antes de pasarle el control al nuevo proceso, el kernel le asigna una porción de
la memoria virtual pero cambiando todas las direcciones de memoria (comenzando de
cero). De esta manera cada proceso cree que dispone de toda la Memoria RAM
Page
Page
Page
…
Page
Page ram
swap
file
kernel
vm
exec
main
funcX
…
a=10
b=20
0x0000
0x0001
0x0002
…
0x0f23
Proceso 1
Process
Address
Space
10. Proceso N
Proceso 2
Lenguaje C
PROCESS ADDRESS SPACE
¿Qué es?
Es el conjunto de direcciones de memoria asignado por el kernel que tiene por objetivo
mostrarse como un recurso de memoria único y exclusivo para cada proceso. Aunque sus
direcciones son virtuales, los datos finalmente son guardados en medios físicos de
almacenamiento (ya sea memoria ram, memoria swap o archivos de disco).
Page
Page
Page
…
Page
Page ram
swap
file
kernel
vm
exec
main
funcX
…
a=10
b=20
0x0000
0x0001
0x0002
…
0x0f23
Proceso 1
Process
Address
Space
11. Lenguaje C
MEMORY MAPS
Sí, más divisiones…
Para que un programa pueda ejecutarse, es necesario
que primero el kernel lo cargue en la memoria. Para
tener un mejor control sobre la memoria asignada, la
«mapea» en diferentes segmentos que comparten
ciertas características. Entre los segmentos principales
tenemos:
• El código ejecutable (llamado .text)
• Múltiples areas de datos como variables
inicializadas, no inicializadas, y el heap
• La pila del programa (program stack)
Estos segmentos (o áreas) son rangos contiguos de
direcciones virtuales que tienen los mismos permisos
Text Segment
Data Segment
Stack Segment
Other Segments…
12. Lenguaje C
MEMORY MAPS
Text Segment
(Código objeto ejecutable)
Data Segment
(char *msg = «Welcome»)
(int ver = 1) (static int res)
Text Segment de librerias
(Librerías ejecutables declaradas via
#include)
Heap Segment
(Usado para Memoria Dinámica)
malloc(40 * sizeof(double))
Stack Segment
(char sign = ‘X’)
(int age) (int a, int b)
(float calc)
Text Segment de librerias SO
(Librerías especiales del SO)
13. Lenguaje C
SECCIONES DE PROGRAMA
¿ Que hay en los segmentos de memoria ?
En general podemos afirmar que en los
segmentos de memoria se mapea un archivo
ejecutable y las librerías que utiliza, pero
¿Qué hay en un archivo ejecutable?
size -Ax <archivo_ejecutable>
Con el comando anterior, podemos ver lo que
hay dentro de un archivo ejecutable, es decir,
un programa en C que ha sido compilado. El
comando mostrará todas las secciones de la
que un programa se compone. El formato
utilizado por un archivo ejecutable se
denomina ELF (Executable Linkable Format)
14. Lenguaje C
SECCIONES DE PROGRAMA
¿ Y que son todas esas secciones ?
Bueno, es a fin de cuentas el programa
compilado. Se divide en secciones porque es
el estándar elegido para el proceso de
desarrollo de software a nivel mundial. El
formato se llama ELF (Executable Linkable
Format)
El SO reconoce el formato ELF como un
archivo ejecutable, que contiene
instrucciones en su seccion .text y que guarda
información necesaria para su correcta
ejecución desde el inicio hasta el final (.init &
.fini) asi como los datos que usa (.data) entre
otros
15. Lenguaje C
SECCIONES DE PROGRAMA
Sección Descripción
.bss Esta sección guarda las variables no inicializadas
.comment Guardar información sobre el control de versiones
.ctors Guarda información sobre los constructores del programa
.data Guarda información de variables inicializadas
.data1 Guarda información de variables inicializadas
.debug Guarda información para depurar un programa
.dtors Guarda información sobre los destructores del programa
.dynamic Guarda información de enlaces dinámicos
.dynstr Guarda las cadenas usadas para el enlazado dinámico
.dynsym Guarda la tabla de símbolos del enlazado dinámico
.fini Guarda las instrucciones del proceso de terminación del programa
.got Guarda la información de la GOT (Global Offset Table)
.hash Guarda información de la tabla hash de los símbolos del programa
.init Guarda las instrucciones del proceso de inicialización del programa
16. Lenguaje C
SECCIONES DE PROGRAMA
Sección Descripción
.interp Guarda la ruta del interprete del programa (usualmente ld)
.line Guarda las líneas de código para el proceso de depuración
.note Guarda información propia del programa
.plt Guarda las posiciones del enlace dinámico del programa
.rel<name> Guarda información de relocación
.rela<name> Guarda información de relocación
.rodata Guarda información de solo lectura del programa
.rodata1 Guarda información de solo lectura del programa
.shstrtab Guarda información de los nombres de las secciones del programa
.strtab Guarda las cadenas utilizadas en el programa
.symtab Guarda la Tabla de simbolos del programa
.text Guarda las intrucciones ejecutables del programa
17. Lenguaje C
SECCIONES Y SEGMENTOS
¿ Cada sección se carga en un segmento de memoria ?
No
Los segmentos de memoria pueden agrupar varias
secciones del programa que comparten características
similares. Por ejemplo, el segmento Text agrupa
secciones referidas a las instrucciones del programa y
sus datos, incluso los permisos son los mismos. Si
analizamos el mapeo de memoria del segmento text
veremos que tiene el r-x (es decir, es una porción
ejecutable, pero en la cual no se puede escribir)
Un caso similar es el segmento Data cuyas secciones
comparten el permiso rw- (porción de memoria que
puede leerse y escribirse pero no ejecutarse)
Text Segment
.text
.rodata .hash
.dynsym .dynstr
.plt
.rel .got
Data Segment
.data
.dynamic
.got
.bss
18. Lenguaje C
LIBRERIAS
¿ Y donde están las librerías ?
Los programas usan librerías las cuales también son mapeados en los segmentos de
memoria. Con el comando ldd podemos ver las librerías que un programa utiliza
19. Lenguaje C
MEMORY MAPS - POC
Prueba de Concepto
Para comprobar como se mapea la
memoria, procedemos a compilar
el programa anterior.
Al ejecutarlo se podrá apreciar
todas las direcciones de memoria
utilizadas por el proceso, desde las
funciones declaradas hasta los
punteros.
Es importante recordar que el mapeo de memoria dura mientras la aplicación no haya
terminado. Por esta razón, hemos forzado a nuestro programa permanecer en ejecución
(vía scanf) para poder apreciar los segmentos que el kernel le ha asignado
20. Lenguaje C
MEMORY MAPS - POC
En Linux, podemos revisar el mapeo de memoria de cualquier proceso con el comando
cat /proc/<id-proceso>/maps
Donde <id-proceso> es el nro de proceso del programa en ejecución
En nuestro ejemplo, el
proceso storage.exe
tiene el ID 3405
Por lo tanto al ejecutar
cat /proc/3405/maps
podemos apreciar el
mapeo de memoria
asignado por el kernel
Y sí, es un poco
intimidante…
21. Lenguaje C
MEMORY MAPS - /proc/<id>/maps
Formato: start-end perm offset major:minor inode image
text
data
text
data
heap
text
text
text
stack
data
bss de ld
data
data
data
bss de libc
reservado
reservado
22. Lenguaje C
MEMORY MAPS - /proc/<id>/maps
Formato: start-end perm offset major:minor inode image
¿Qué información muestra?
start-end : Indica las direcciones de memoria virtuales de inicio y fin del segmento
perm : Permisos del segmento (r=read, w=write, x=executable, p=private, s=shared)
offset : Nro direcciones de memoria a desplazar desde el start-end (0=inicio de archivo)
major:minor : Nros del dispositivo que tiene archivo mapeado (0:0=ram, fd:0=disco)
inode : Nro inode del archivo mapeado (identificador numérico del archivo abierto)
image : Nombre del archivo ejecutable mapeado o nombre del segmento de memoria
23. Lenguaje C
ASIGNACION DE MEMORIA
Ahora sí, a lo nuestro !
El lenguaje C permite manejar 3 tipos de asignación de memoria para las variables
• Asignación Estática
Esta asignación ocurre cuando se declara una variable global o static. El espacio es
asignado una sola vez y ocurre cuando el programa inicia y no se libera hasta su fin
• Asignación Automática
Ocurre cuando se declara una variable automática (como un argumento de función o
una variable local). El espacio para una variable automática reside en el ámbito de la
función o el bloque del programa en el cual reside y termina al finalizar dicho bloque o
función. En términos de segmentos, las variables automáticas están en la pila o Stack
• Asignación Dinámica
Este tipo de asignación no es soportado por las variables de C, sin embargo está
disponible mediante la librería de funciones estándar de C
24. Lenguaje C
ASIGNACION DINAMICA
¿Qué es la Asignación Dinámica de Memoria?
Es una técnica que permite obtener memoria en tiempo de ejecución. Se utiliza cuando
no tenemos información previa sobre la cantidad de memoria que nuestro programa va a
utilizar. De esta manera podremos asignar memoria «al vuelo» y no quedarnos sin ella.
¿Y dónde se guardan los datos asignados dinámicamente?
Buena pregunta! Se guardan en el Heap Segment (¿te parece conocido?)
25. Lenguaje C
ASIGNACION DINAMICA – HEAP SEGMENT
¿Qué es el Heap Segment?
Es un segmento de memoria donde se guarda la
información de un proceso que utiliza asignación
dinámica.
Usualmente al crearse un proceso; el kernel le
asigna 32 ó 33 pages de espacio (128KB ó 132KB).
Sin embargo, si es necesario mas memoria, el
kernel se ocupará de ampliar el segmento cuando
se requiera
Es importante recordar que el Heap Segment tiene
privilegios de lectura y escritura pero no de
ejecución (es decir, nada alojado en este segmento
será tratado como instrucciones ejecutables) y su
dominio es privado
Heap
0x01a70000 Datos
0x01a70001 Datos
0x01a70002 Datos
… Datos
0x01a90FFFF Datos
0x01a91000 Datos
33
Pages
Privilegios: rw-p
26. Lenguaje C
ASIGNACION DINAMICA – HEAP SEGMENT
¿Cómo se usa el Heap Segment?
Como hemos mencionado, el lenguaje C no
soporta asignación dinámica para sus variables, es
decir NO podemos indicar algo como esto:
dinamic char texto[100];
Si no queda muy claro el ejemplo, usaremos
Javascript para simular lo que sería una variable
dinámica
var texto; //no se declaran limites
Sí, es lamentable pero, es lo que tenemos por
ahora. En su lugar debemos utilizar las llamadas
del sistema operativo para efectuar esta tarea
Heap
0x01a70000 Datos
0x01a70001 Datos
0x01a70002 Datos
… Datos
0x01a90FFFF Datos
0x01a91000 Datos
33
Pages
Privilegios: rw-p
27. Lenguaje C
ASIGNACION DINAMICA – HEAP SEGMENT
¿Cómo se usa el Heap Segment?
Usualmente, las librerías de C permiten utilizar las
llamadas al sistema para asignar memoria
dinámica. Es importante entender que la
asignación dinámica de memoria solo es posible a
través del uso de punteros.
Heap
0x01a70000 Datos
0x01a70001 Datos
0x01a70002 Datos
… Datos
0x01a90FFFF Datos
0x01a91000 Datos
33
Pages
Privilegios: rw-p
0x765d3
0x01a90ffff
char*
ptr
Esto agrega complejidad y requiere mayor tiempo
de cpu, por lo que debemos utilizarla cuando las
otras 2 (estática y automática) no nos solucionen
el problema de almacenamiento
28. Lenguaje C
ASIGNACION DINAMICA – MALLOC
Usando Malloc
Malloc es la función que permite asignar memoria
dinámica. Su uso es muy simple
#include <stdlib.h>
void* malloc (size_t size);
Una llamada a malloc asignará size bytes de
memoria del Heap Segment y retornará un
puntero a la primera dirección de memoria de la
nueva región asignada. Los datos de la memoria
asignada no serán inicializados y si ocurre una falla
la función malloc retornará NULL y el errno será
seteado a ENOMEM
29. Lenguaje C
ASIGNACION DINAMICA – MALLOC
Usando Malloc
Al utilizar malloc, no es necesario realizar la
conversión al tipo de dato debido a que el
lenguaje C acomoda los tipos void de la función
malloc al tipo de dato de destino.
En el ejemplo se puede apreciar el uso de la
función malloc para asignar espacio suficiente para
almacenar una estructura de datos.
Nótese que no se requiere la conversión al tipo de
dato struct _data*. Solo se necesita la llamada a
malloc enviándole el tamaño de la estructura.
Sin embargo, la conversión puede ayudar en caso
se necesite ejecutar en código C tradicional
30. Lenguaje C
ASIGNACION DINAMICA – MALLOC
Usando Malloc
La función malloc puede fallar cuando el kernel no
es capaz de asignar la cantidad de memoria
solicitada. En ese caso retornara NULL
Es muy importante verificar siempre el resultado
retornado por la función malloc. Para ello, los
desarrolladores usan una técnica denominada
wrapper, que consiste en una envoltura para la
función malloc que permite manejar los errores en
caso no pueda asignarse la memoria solicitada.
En el ejemplo, podemos ver la función wrapper
llamada xmalloc
31. Lenguaje C
ASIGNACION DINAMICA – CALLOC
Asignando Arrays Dinámicos
La asignación dinámica puede ser algo compleja
sobretodo cuando el tamaño de la variable es
dinámico. Es es caso de los Arrays, donde sus
elementos pueden ser de un tamaño fijo, pero el
número de elementos es dinámico
En estos casos, usamos la función calloc
#include <stdlib.h>
void* calloc (size_t nr, size_t size);
La función calloc, permite indicar el número de
elementos que desean asignarse dinámicamente
de un tamaño especifico
32. Lenguaje C
ASIGNACION DINAMICA – CALLOC
Asignando Arrays Dinámicos
En el ejemplo podemos apreciar la asignación de
100 enteros (array de enteros) usando las
funciones calloc y malloc
El comportamiento de ambas funciones es
idéntico, sin embargo hay una diferencia
sustancial: calloc inicializa los datos a cero.
La función malloc devuelve datos aleatorios, sin
inicializarlos, por lo que es necesario recurrir a
otras funciones para realizar esta tarea.
En el ejemplo, la variable ‘a’ apunta a 100 valores
enteros inicializados a cero, mientras que la
variable ‘b’ apunta a 100 valores enteros aleatorios
33. Lenguaje C
ASIGNACION DINAMICA – REALLOC
Redimensionando Memoria Dinámica
Algunas veces, al asignar memoria no se conoce
con exactitud el tamaño del bloque que se
necesita para almacenar la información requerida
En esos casos, se puede usar la función realloc
#include <stdlib.h>
void* realloc (void* ptr, size_t size);
La función realloc redimenciona en size bytes la
región de memoria apuntada por ptr. La
redimensión puede ser para aumentar o disminuir
el tamaño de memoria
34. Lenguaje C
ASIGNACION DINAMICA – REALLOC
Redimensionando Memoria Dinámica
La función realloc evalúa si puede alargar la región
de memoria in situ. Si no puede hacerlo, creara
otra región de memoria y trasladara los datos de la
región original para luego liberarla.
Cualquiera que sea la forma, los datos se
preservan durante una llamada a realloc.
Si ocurre alguna falla durante la redimensión, la
función retornara NULL, seteara la variable global
errno a ENOMEM, y el estado de la variable ptr
queda inalterado
35. Lenguaje C
ASIGNACION DINAMICA – FREE
Liberando Memoria Dinámica
Es casi seguro que no teníamos la menor idea de
que el intérprete de C se ocupaba de liberar la
memoria de nuestras variables estáticas o
automáticas. El precio por desconocer eso es caro,
dado que es muy fácil olvidar que al usar memoria
dinámica debemos ocuparnos de liberarlas
explícitamente
#include <stdlib.h>
void free(void* ptr);
La función free, permite liberar la memoria
previamente asignada a ptr por malloc o calloc
36. Lenguaje C
ASIGNACION DINAMICA – MEMORY MAPPINGS
Anonymous Memory Mappings
Las funciones malloc / calloc son útiles para
asignaciones de memoria a pequeña escala. Pero
cuando necesitamos cantidades mayores de
memoria, el sistema no usa el Heap Segment sino
Segmentos hechos a medida.
Asignando memoria mediante anonymous
mapping permite evitar los problemas de
fragmentación habituales en malloc. También
permite ajustar los permisos de todo el segmento.
Sin embargo su uso puede resultar en un aumento
de la carga del sistema.
Anonymous Mapping
0x02a70000 Datos
0x02a70001 Datos
0x02a70002 Datos
… Datos
0x02a90FFFF Datos
0x02a91000 Datos
X
Pages
Privilegios Personalizados y
Ajustables
37. Lenguaje C
ASIGNACION DINAMICA – MEMORY MAPPINGS
Crear un Anonymous Memory Mapping
Para crear un segmento de memoria
debemos usar la función mmap
#include <sys/mman.h>
void* mmap(void* start,
size_t length,
int prot,
int flags,
int fd,
off_t offset);
Para indicar que será anónimo se debe setear
los flags a MAP_ANONYMOUS |
MAP_PRIVATE
38. Lenguaje C
ASIGNACION DINAMICA – MEMORY MAPPINGS
Crear un Anonymous Memory Mapping
En el ejemplo podemos ver la reserva de
1MB de tamaño via Anonymous Memory
Mapping.
Un uso habitual es cargar un archivo en
memoria mediante Anonymous Memory
Mapping., para ello debemos enviar el File
Descriptor en el penúltimo parámetro en
lugar del valor -1
La ventaja es que se puede manipular los
permisos al segmento de memoria al
momento de crearlo
39. Lenguaje C
ASIGNACION DINAMICA – MEMORY MAPPINGS
Eliminar un Anonymous Memory Mapping
Al igual que malloc, la memoria asignada via
Anonymous Memory Mapping debe ser
liberada una vez que ya no se va a utilizar.
Para liberar memoria usamos la función
munmap.
#include <sys/mman.h>
int munmap(void* start, size_t length)
Para liberar memoria usamos la funcion
munmap.
40. Lenguaje C
ASIGNACION DINAMICA – STACK SEGMENT
¿Qué es el Stack Segment?
Hasta ahora, para obtener memoria dinámicas
hemos usado el Heap o Memory Mappings. Sin
embargo hay otro mecanismos para asignarla. La
pila (stack) puede ser utilizada para asignar
memoria dinámica. Recordemos que en la pila se
guardan las variables del programa. Eso no quiere
decir que no se pueda usar como memoria
dinámica. De hecho, es muy sencillo hacerlo
mediante la función alloca
#include <alloca.h>
void *alloca( size_t size );
41. Lenguaje C
ASIGNACION DINAMICA – STACK-BASED
Asignación vía Stack
En el ejemplo se puede observar que el uso de la
función alloca es identica a malloc. De hecho,
funciona de forma similar. La diferencia es interna
ya que los datos no son guardados en el Heap sino
en la región de la Stack.
La ventaja que tiene la Stack sobre el Heap, es que
en esta región, las variables se manejan más
rápido y de forma automática, es decir no hay
necesidad de liberarlas ya que el Sistema
Operativo se encarga de hacerlo. Una vez
finalizado el programa o la función donde es
declarado la función alloca, automáticamente se
liberará la memoria.
42. Lenguaje C
ASIGNACION DINAMICA – STACK-BASED
Duplicando cadenas
Un uso muy común de la función alloca() es
duplicar cadenas de forma temporal
En Linux existen funciones basadas en alloca() que
aprovechan esta característica de alojar datos en la
stack. Entre otras funciones tenemos:
#include <string.h>
char *strdupa( const char* s);
char *strndupa( const char* s, size_t n);
Sin embargo, estas funciones junto con alloca() solo existen para Linux por lo que no se
recomienda usarlas en proyectos portables ya que no son estándares POSIX
43. Lenguaje C
ASIGNACION DINAMICA – STACK-BASED
Duplicando cadenas
La función strdupa y strndupa duplican las cadenas
enviadas y las guardan en el Stack Segment.
La diferencia entre ambas funciones radica en que
strdupa hace una copia total mientras que
strndupa hace una copia de n caracteres
Ambas funciones no requieren liberar la memoria
reservada después de ser utilizadas, pues se hará
de forma automática
Ambas funciones deben ser compiladas via GCC con la opción -D_GNU_SOURCE
(ejemplo: gcc -D_GNU_SOURCE strnupa.c -o strndupa.exe)
44. Lenguaje C
ASIGNACION DINAMICA – STACK-BASED
Arrays de longitud variable
Durante mucho tiempo, los arrays tenían que ser
declarados con dimensiones fijas y muchas veces
se caía en el exceso o falta de espacio
Con el estándar C99, el lenguaje C adopta un
nuevo mecanismo de asignación dinámica
mediante el uso de arrays de longitud variable
(VLA)
Los VLA permiten dimensionar en tiempo de
ejecución el tamaño de un array
Como se puede apreciar en el ejemplo, el tamaño del array path depende de la longitud
de las variables conf y file.
45. Lenguaje C
ASIGNACION DINAMICA – BONUS TRACK
La Función memset
La gran mayoría de programadores utiliza la
función malloc sin considerar que el espacio de
memoria devuelto contiene información no
inicializada.
Es muy común lanzar maldiciones cuando nuestro
programa muestra información que se supone no
debería estar ahí. Por eso, si utilizamos malloc,
debemos inicializar siempre el espacio de memoria
retornado. La función memset nos puede ayudar
con esa tarea
Como se puede apreciar en el ejemplo, la cadena nombre es inicializada con el carácter
NULO (‘0’) en sus 50 elementos
46. Lenguaje C
OTRAS FUNCIONES DE MEMORIA
¿Aun hay más?
Sí, mucho más. Las funciones de memoria que se han tratado en este documento son
las funciones básicas y que no requieren del conocimiento de otro tópico del Sistema
Operativo para entenderlas
Funciones de Manipulación (memmove, memchr, memrchr, memmem, memfrob)
Funciones de Bloqueo (mlock, mlockall, munlock, munlockall, mincore)
Funciones de Depuración (mallinfo, malloc_stats)
Funciones Avanzadas de Asignación (mallopt, malloc_usable_size, malloc_trim, brk)
Funciones de Alineamiento (posix_memalign, memalign, valloc
47. Lenguaje C
ASIGNACION DINAMICA – COMPARACIONES
Método Pro Contra
malloc() Simple, fácil y común Retorna memoria no
inicializada
calloc() Hace simple la asignación de arrays,
retorna memoria inicializada
Complicado si no se asignan
arrays
realloc() Redimensiona asignaciones existentes Util solo para memoria
previamente asignada
Anonymous
Mapping
Potente y altamente personalizable Ineficiente para asignaciones
pequeñas de memoria
alloca() Asignación muy rápida, no requiere
liberar memoria
No permite retornar error,
útil solo para asignaciones
pequeñas y no es estándar
VLA Similar a alloca() Solo para arrays
48. Lenguaje C
RECOMENDACIONES Y REGLAS
Asigna y libera memoria en el mismo módulo o función
Asigna un nuevo valor o NULL a un puntero después de usar free()
No uses conversión de tipos (typecast) con malloc
Limpia la memoria con información sensible (usando memset)
Asegúrate que el argumento size de la funcion malloc no sea cero
Evitar asignaciones de stack desmesuradas
Cuando uses calloc, asegúrate de no desbordar el tipo de dato size_t
No se debe asumir que el Heap Segment tiene espacio ilimitado
No se debe acceder al espacio de memoria liberada con free()
Liberar memoria cuando ya no se necesita
Solo se debe liberar memoria dinámica
Asigna suficiente memoria para un objeto con su mismo tipo de dato
Fuente: https://www.securecoding.cert.org/confluence/pages/viewpage.action?pageId=437
49. Lenguaje C
Anexos
¿Qué necesito para programar en C bajo Linux?
gcc, gdb, vim
¿Cómo compilar un programa C en Linux?
gcc mi-programa.c -g -o mi-programa.exe
¿Cómo depurar un programa C en Linux?
gdb mi-programa.exe
¿Qué necesito para programar en C bajo Windows?
Visual C++ ó Borland C ó C Builder, etc
Nota: La extensión .exe es
solo para referencia
sencilla de que se trata
de un ejecutable, no es
necesario por lo tanto
agregarle dicha extensión
en realidad
Nota: Si se desea
programar con el
estándar C11 se deberá
obtener una copia del
compilador gcc 4.8.1.
50. Lenguaje C
Bibliografía
Linux System Programming, Second Edition by Robert Love
Linux Device Drivers 3rd Edition, Jonathan Corbet, Alessandro Rubini & Greg Kroah-
Hartman
Understanding the Linux Kernel, 3rd Edition, Daniel P.Bovet & Marco Cesati
CERT C Programming Language Secure Coding Standard, Document No. N1255
Executable and Linking Format (ELF) Specification Version 1.2, TIS Committee
The GNU C Library Reference Manual, Sandra Loosemore
with Richard M. Stallman, Roland McGrath, Andrew Oram, and Ulrich Drepper
51. Lenguaje C
Bibliografía
The C Programming Language, 2nd Edition, B. Kernighan, Dennis Ritchie.
The Art and Science of C, Eric S. Roberts.
Programming in C, 3rd Edition, Stephen G. Kochan
Programación en C, Metodología, algoritmos y estructura de datos. Luis Joyanes
Aguilar
C Programming A Modern Approach. Second Edition. K.K.King