Gerenciamento de Memória
Alocação Dinâmica de Memória
Funções Fundamentais de Alocação de Memória
char *str = malloc(50 * sizeof(char)); // Alocar memória
if (str == NULL) {
// Lidar com falha de alocação
fprintf(stderr, "Falha na alocação de memória\n");
exit(1);
}
// Usar a string
strcpy(str, "Hello, LabEx!");
// Sempre liberar memória alocada dinamicamente
free(str);
Estratégias de Alocação de Memória
graph TD
A[Alocação de Memória]
A --> B[malloc()]
A --> C[calloc()]
A --> D[realloc()]
A --> E[free()]
Métodos de Alocação de Memória
| Função |
Finalidade |
Comportamento |
| malloc() |
Alocação básica |
Memória não inicializada |
| calloc() |
Alocação limpa |
Zera a memória |
| realloc() |
Redimensionar alocação |
Preserva dados existentes |
Alocação Segura de Strings
char* create_string(size_t length) {
char *new_str = malloc((length + 1) * sizeof(char));
if (new_str == NULL) {
return NULL; // Alocação falhou
}
new_str[length] = '\0'; // Garantir terminação nula
return new_str;
}
Prevenção de Vazamentos de Memória
char* process_string(const char* input) {
char* result = malloc(strlen(input) + 1);
if (result == NULL) {
return NULL;
}
strcpy(result, input);
return result;
}
// Uso correto
char* str = process_string("Example");
if (str != NULL) {
// Usar a string
free(str); // Sempre liberar
}
Gerenciamento Avançado de Memória
Realocando Strings
char* expand_string(char* original, size_t new_size) {
char* expanded = realloc(original, new_size);
if (expanded == NULL) {
free(original); // Liberar original se realloc falhar
return NULL;
}
return expanded;
}
Armadilhas Comuns
- Esquecer de liberar memória alocada.
- Usar memória após liberação.
- Estouro de buffer.
- Cálculos incorretos de tamanho de memória.
Boas Práticas
- Sempre verificar os resultados de alocação.
- Liberar memória quando não mais necessária.
- Usar valgrind para detecção de vazamentos de memória.
- Preferir alocação na pilha quando possível.
No LabEx, recomendamos um gerenciamento cuidadoso de memória para criar programas C robustos.
Técnica de Rastreamento de Memória
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);
}
}