C结构中的内存错误

时间:2012-03-08 10:27:50

标签: c memory

对于较大的MAXV值,以下代码会导致insert_edge函数(在行p-> next = g-> edges [x]中猜测)中出现内存错误。对于较小的,效果很好。问题出在哪儿?如何定义它的结构?

#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");//  
    }

4 个答案:

答案 0 :(得分:2)

graph g;

graph明确地太大而无法放在堆栈上。把它放在堆中:

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

并遵循格雷厄姆的建议。即使是堆也可能太大了。

答案 1 :(得分:2)

看起来它可能是堆栈溢出。 graph是一个大型数据结构,您在main中在本地(即在堆栈上)分配它。尝试将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;
}

答案 2 :(得分:1)

您是否正在检查此malloc的返回值?

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

可能是你的内存不足。在继续之前检查p是否NULL

答案 3 :(得分: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;