es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Malloc rompe la función.

Tengo un problema donde mi malloc rompe mi programa. Eliminarlo hará que funcione, pero lo necesito más adelante. ¿Alguien puede explicarme qué estoy haciendo mal? ¡Gracias de antemano!

Tengo esta función en mi graph.c

bool graph_initialise(graph_t graph, unsigned vertex_count)
{
  assert(graph != NULL);
  graph = (struct graph_s) malloc(sizeof(struct graph_s));
  if (graph == NULL){return true;}
  graph->vertex_count = vertex_count;

  graph->adjacency_lists = (struct adjacency_list_s*) malloc(vertex_count * sizeof(struct adjacency_list_s));
  if (graph->adjacency_lists == NULL){
    return true;
  }

  int i;
  for (i = 1; i < vertex_count; ++i){
    graph->adjacency_lists[i].first = NULL;
  }

  return false;
}

y esto en mi graph.h

typedef struct edges
{
  /* Points to the next edge when this edge is part of a linked list. */
  struct edges *next;

  unsigned tail;    /* The tail of this edge. */
  unsigned head;    /* The head of this edge. */
  unsigned weight;  /* The weight of this edge. */
} edge_t;

typedef struct adjacency_lists
{
  edge_t *first; /* Pointer to the first element of the adjacency list */
} adjacency_list_t;

/* Type representing a graph */
typedef struct graph_s
{
  unsigned vertex_count; /* Number of vertices in this graph. */
  unsigned edge_count;   /* Number of edges in this graph. */

  /* Pointer to the first element of an array of adjacency lists. The array
   * is indexed by vertex number
   */
  adjacency_list_t *adjacency_lists;
} graph_t;
Tags:  , , ,

Answer

  1. Avatar for davy.ai

    El problema con el código es que la memoria asignada para graph en la función graph_initialise está siendo sobrescrita, y el puntero se pasa por valor. Esto significa que los cambios realizados en este puntero en la función no se propagan al llamador.

    Para solucionar este problema, debemos asignar memoria para graph en la función del llamador y pasar un puntero a esa memoria a graph_initialise. La firma de la función debe cambiarse a bool graph_initialise(graph_t **graph_ptr, unsigned vertex_count), y la asignación debe hacerse en el llamador de la siguiente manera:

    graph_t *graph;
    graph = (graph_t*) malloc(sizeof(graph_t));
    bool error = graph_initialise(&graph, vertex_count);
    if (error) {
      // manejar error
    }
    

    La función graph_initialise debe ser modificada para desreferenciar el puntero a graph para acceder y modificar sus campos:

    bool graph_initialise(graph_t **graph_ptr, unsigned vertex_count) {
      *graph_ptr = (graph_t*) malloc(sizeof(graph_t));
      if (*graph_ptr == NULL) { return true; }
    
      (*graph_ptr)->vertex_count = vertex_count;
    
      (*graph_ptr)->adjacency_lists = (adjacency_list_t*) malloc(vertex_count * sizeof(adjacency_list_t));
      if ((*graph_ptr)->adjacency_lists == NULL) {
        return true;
      }
    
      int i;
      for (i = 0; i < vertex_count; ++i) {
        (*graph_ptr)->adjacency_lists[i].first = NULL;
      }
    
      return false;
    }
    

    Al hacer esto, el llamador puede usar de forma segura el puntero graph después de la llamada a graph_initialise.

Comments are closed.