Gestión de Memoria
Asignación Dinámica de Memoria
Funciones Fundamentales de Asignación de Memoria
char *str = malloc(50 * sizeof(char)); // Asignar memoria
if (str == NULL) {
// Manejar el fallo de asignación
fprintf(stderr, "Error en la asignación de memoria\n");
exit(1);
}
// Usar la cadena
strcpy(str, "Hello, LabEx!");
// Siempre liberar la memoria asignada dinámicamente
free(str);
Estrategias de Asignación de Memoria
graph TD
A[Asignación de Memoria]
A --> B[malloc()]
A --> C[calloc()]
A --> D[realloc()]
A --> E[free()]
Métodos de Asignación de Memoria
| Función |
Propósito |
Comportamiento |
| malloc() |
Asignación básica |
Memoria sin inicializar |
| calloc() |
Asignación inicializada |
Memoria inicializada a cero |
| realloc() |
Reasignación de tamaño |
Preserva los datos existentes |
Asignación Segura de Cadenas
char* create_string(size_t length) {
char *new_str = malloc((length + 1) * sizeof(char));
if (new_str == NULL) {
return NULL; // Fallo en la asignación
}
new_str[length] = '\0'; // Asegurar la terminación nula
return new_str;
}
Prevención de Fugas de Memoria
char* process_string(const char* input) {
char* result = malloc(strlen(input) + 1);
if (result == NULL) {
return NULL;
}
strcpy(result, input);
return result;
}
// Uso correcto
char* str = process_string("Example");
if (str != NULL) {
// Usar la cadena
free(str); // Siempre liberar
}
Gestión Avanzada de Memoria
Reasignación de Cadenas
char* expand_string(char* original, size_t new_size) {
char* expanded = realloc(original, new_size);
if (expanded == NULL) {
free(original); // Liberar original si realloc falla
return NULL;
}
return expanded;
}
Errores Comunes
- Olvidar liberar la memoria asignada.
- Usar memoria después de liberarla.
- Desbordamiento de búfer.
- Cálculos incorrectos del tamaño de la memoria.
Buenas Prácticas
- Siempre comprobar los resultados de la asignación.
- Liberar la memoria cuando ya no se necesita.
- Usar valgrind para detectar fugas de memoria.
- Preferir la asignación en la pila cuando sea posible.
En LabEx, recomendamos una gestión cuidadosa de la memoria para crear programas C robustos.
Técnica de Seguimiento de Memoria
typedef struct {
char* data;
size_t size;
} SafeString;
SafeString* create_safe_string(size_t length) {
SafeString* safe_str = malloc(sizeof(SafeString));
if (safe_str == NULL) return NULL;
safe_str->data = malloc(length + 1);
if (safe_str->data == NULL) {
free(safe_str);
return NULL;
}
safe_str->size = length;
safe_str->data[length] = '\0';
return safe_str;
}
void free_safe_string(SafeString* safe_str) {
if (safe_str != NULL) {
free(safe_str->data);
free(safe_str);
}
}