2012-03-08 3 views
0

Следующий код вызывает ошибку памяти в функции insert_edge (в строке p-> next = g-> edge [x], я думаю) для больших значений MAXV. Для маленьких он отлично работает. В чем проблема? Как определить структуру, в которой он работает?Ошибка памяти в C struct

#include <stdlib.h> 
#include <stdio.h> 

#define MAX_LINE_SIZE (1024*128) 


#define MAXV  23947347  /* maximum number of vertices */ 
#define NULLO    0  /* null pointer */ 


#define TRUE 1 
#define FALSE 0 

typedef int bool; 

typedef struct edgenode { 
    int y;    /* adjancency info */ 
    int weight;   /* edge weight, if any */ 
    struct edgenode *next;  /* next edge in list */ 
} edgenode; 


typedef struct { 
    edgenode *edges[MAXV+1]; /* adjacency info */ 
    int degree[MAXV+1];  /* outdegree of each vertex */ 
    int nvertices;   /* number of vertices in the graph */ 
    int nedges;   /* number of edges in the graph */ 
    int directed;   /* is the graph directed? */ 
} graph; 

initialize_graph(graph *g, bool directed) 
{ 
    int i;    /* counter */ 

    g -> nvertices = 0; 
    g -> nedges = 0; 
    g -> directed = directed; 

    for (i=1; i<=MAXV; i++) 
      g->degree[i] = 0; 
    for (i=1; i<=MAXV; i++) 
      g->edges[i] = NULL; 
} 

read_graph(graph *g, bool directed, const char *filename) 
{ 

    FILE *f; 
    char line[MAX_LINE_SIZE], buf[10]; 
    int format, rc; 
    int edge; 
    int vertex_n; 
    int vertex_m; 

    char *token,*token2, *s; 

    int v; 

    int i;    /* counter */ 

    /* open file */ 
    f = fopen (filename, "r"); 
    if (f == NULL) 
     return NULL; 


    rc = sscanf (line, "%d %d %d", &(vertex_n), &(vertex_m), &(edge)); 

    initialize_graph(g, directed); 

    for (i=1; i<=edge; i++) { 
     s = fgets (line, MAX_LINE_SIZE, f); 

     token = strtok (line, " "); 

     token2 = strtok (NULL, " "); 

     int s = atoi(token); 
     int t = atoi(token2); 

     printf("%d, %d\n", start, ziel); 

     insert_edge(g,s,t,directed); 

} 

} 

insert_edge(graph *g, int x, int y, bool directed) 
{ 
    edgenode *p;   /* temporary pointer */ 

    p = malloc(sizeof(edgenode)); /* allocate storage for edgenode */ 

    p->weight = NULL; 
    p->y = y; 
    p->next = g->edges[x]; 
     g->edges[x]; 

    g->edges[x] = p;  /* insert at head of list */ 

    g->degree[x] ++; 

    if (directed == FALSE) 
     insert_edge(g,y,x,TRUE); 
    else 
     g->nedges ++; 
} 

    main() 
    { 
     graph g; 

     read_graph(&g,FALSE, "/path/graph_with_23947347_nodes.mtx");// 
    } 
+0

K & R C? Вам лучше переключиться на ANSI. –

+0

Насколько велики ваши «большие значения MAXV»? – Jay

+0

Проверьте, что параметр x не находится вне привязки (MAXV) – ydroneaud

ответ

2
graph g; 

является окончательно слишком большой, чтобы поместиться в стеке. Вместо этого поставьте его в кучу:

graph* g=malloc(sizeof(graph)); 

И следуйте советам Грэма. Это может быть слишком большим даже для кучи.

+0

У меня достаточно памяти;) Но это была проблема. Спасибо! – ItsameMario

1

Вы проверяете возвращаемое значение из этого malloc?

p = malloc(sizeof(edgenode)); /* allocate storage for edgenode */ 

Возможно, вы просто исчерпали память. Перед тем, как продолжить, убедитесь, что p не NULL.

0
p->next = g->edges[x]; 
     g->edges[x]; 

    g->edges[x] = p;  /* insert at head of list */ 

Этот код не имеет никакого смысла.

В односвязном списке вы не можете вставить новый узел до существующего узла, не указав перед ним предыдущий узел. В противном случае, как предыдущий узел может обновить следующий указатель?

Это вставляет свой узел после существующего узла:

p->next = g->edges[x]->next; 
g->edges[x]->next = p; 
2

Похоже, что это может быть переполнение стека. - это большая структура данных, и вы размещаете ее локально (т. Е. В стеке) в main. Попробуйте изменить основную на:

int main(void) 
{ 
    graph *g = malloc(sizeof(graph)); 
    if (g != NULL) 
    { 
     read_graph(g, FALSE, "/path/graph_with_23947347_nodes.mtx"); 
     free(g); 
    } 
    return 0; 
} 
Смежные вопросы