Asignación de memoria estructural con malloc en C
-
Utiliza
malloc
con el operadorsizeof
para asignar memoria estructural en C -
Utilizar el bucle
for
para asignar memoria a un array de estructuras en C
Este artículo explicará varios métodos de cómo asignar memoria struct con malloc
en C.
Utiliza malloc
con el operador sizeof
para asignar memoria estructural en C
malloc
es la función principal para la asignación dinámica de memoria en C que toma un único argumento entero que representa el número de bytes a asignar. Para asignar la memoria del objeto struct
personalizado que se ha definido, debemos llamar al operador sizeof
y recuperar la cantidad de memoria que necesita el objeto para ser almacenado.
Ten en cuenta que podemos pasar la expresión sizeof(MyObject)
directamente a la llamada malloc
como argumento. Una advertencia sobre malloc
es que la memoria asignada con éxito no se inicializa, lo que significa que puede haber algunos valores basura almacenados. Para contrarrestar este problema, la biblioteca C proporciona otra función útil - calloc
para inicializar automáticamente la región de memoria con cero. El siguiente ejemplo muestra la asignación de memoria para la estructura única MyObject
.
#include <stdio.h>
#include <stdlib.h>
enum VALID { FALSE, TRUE };
typedef struct {
int valid;
int *data;
size_t size;
} MyObject;
int main() {
int *tmp = NULL;
MyObject *my1 = malloc(sizeof(MyObject));
my1->valid = TRUE;
my1->data = tmp;
my1->size = sizeof tmp;
free(my1);
exit(EXIT_SUCCESS);
}
Utilizar el bucle for
para asignar memoria a un array de estructuras en C
A menudo es útil declarar un array de estructuras, que puede requerir una región de memoria mayor que la disponible en la pila. Por lo tanto, necesitamos asignar el array como memoria dinámica. El siguiente código de ejemplo demuestra el caso en que el array de 100 punteros a los structs MyObject
se declara en la pila, pero cada objeto individual MyObject
se asigna en memoria dinámica (heap).
Ten en cuenta que también hemos implementado la función initMyObject
para inicializar cada miembro de MyObject
sólo con fines de prueba. La función devuelve -1
si el puntero pasado es null
, y la sentencia if
se pone en el bucle for
para asegurarse de que se imprime el mensaje de error correspondiente.
#include <stdio.h>
#include <stdlib.h>
#define MAX 100
enum VALID { FALSE, TRUE };
typedef struct {
int valid;
int *data;
size_t size;
} MyObject;
int initMyObject(MyObject *obj, int val, int *dat, size_t siz) {
if (!obj) return -1;
obj->valid = val;
obj->data = dat;
obj->size = siz;
return 0;
}
int main() {
int *tmp = NULL;
MyObject *arr[MAX];
for (int i = 0; i < MAX; ++i) {
arr[i] = malloc(sizeof(MyObject));
if (initMyObject(arr[i], TRUE, tmp, sizeof(tmp)) == -1) {
fprintf(stderr, "[ERROR] initMyObject() failed\n");
break;
}
}
printf("finished\n");
exit(EXIT_SUCCESS);
}
Aunque, hay una parte errónea del programa anterior que no se puede permitir en ningún código de producción. El programa sale sin desasignar las regiones de memoria que han sido asignadas dinámicamente en el bucle. Nótese que, al igual que la asignación, cada elemento individual del array debe ser liberado. Por lo tanto, implementamos una función separada, deallocMyObjectArray
, para ejecutar llamadas iterativas a free
en el siguiente ejemplo de código.
#include <stdio.h>
#include <stdlib.h>
#define MAX 100
enum VALID { FALSE, TRUE };
typedef struct {
int valid;
int *data;
size_t size;
} MyObject;
int initMyObject(MyObject *obj, int val, int *dat, size_t siz) {
if (!obj) return -1;
obj->valid = val;
obj->data = dat;
obj->size = siz;
return 0;
}
int deallocMyObjectArray(MyObject *arr[], size_t len) {
if (!arr) return -1;
for (int i = 0; i < len; ++i) free(arr[i]);
return 0;
}
int main() {
int *tmp = NULL;
MyObject *arr[MAX];
for (int i = 0; i < MAX; ++i) {
arr[i] = malloc(sizeof(MyObject));
if (initMyObject(arr[i], TRUE, tmp, sizeof(tmp)) == -1) {
fprintf(stderr, "[ERROR] initMyObject() failed\n");
break;
}
}
deallocMyObjectArray(arr, MAX);
printf("finished\n");
exit(EXIT_SUCCESS);
}
Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.
LinkedIn Facebook