2012-03-08 7 views
0

次のコードは、大きなMAXV値の場合、insert_edge関数(p> next = g-> edges [x])のメモリエラーを引き起こします。小さいものの場合はうまくいく。問題はどこだ?それが動作する構造体をどのように定義できますか?C構造体のメモリエラー

#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)); 

また、Grahamのアドバイスに従ってください。ヒープでも大きすぎるかもしれません。

+0

私は十分な記憶があります;)しかし、これは問題でした。ありがとうございました! – ItsameMario

1

mallocからの戻り値を確認していますか?

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

メモリが不足している可能性があります。続行する前にpNULLでないことを確認してください。

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; 
}