Asignación de memoria estructural con malloc en C

Jinku Hu 12 octubre 2023
  1. Utiliza malloc con el operador sizeof para asignar memoria estructural en C
  2. Utilizar el bucle for para asignar memoria a un array de estructuras en C
Asignación de memoria estructural con malloc 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);
}
Autor: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

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

Artículo relacionado - C Struct