代码运行正常,但Debug给出"分段错误"

时间:2015-12-21 17:11:07

标签: c graph codeblocks void-pointers

我在构建一个用图表执行各种操作的程序时遇到了这个问题。 我使用代码块在C中编写代码,如果我正常运行它(通过"构建和运行")程序"工作" (它仍未完成),但如果我尝试通过调试器运行代码,它将以Segmentation fault停止。这很奇怪。

以下是我的代码的一些摘录,以解决这个问题,抱歉这个烂摊子:

的main.c

FILE *file;
char *input = "input.txt";
file = fopen(input, "r"); // Open the file read-only
if(file != NULL){
    G = parse(file, F);        // Parse the graph
fclose(file);  // Close the file

Graph.h

struct TGraph {
    void **adj;
    int nodes_count;
};

typedef struct TGraph *Graph;
typedef enum GraphType {LIST, MATRIX} GraphType;

typedef Graph (*INITGRAPH)(int);
typedef void (*ADDADJ)(Graph, int, int, float);
typedef void (*PRINT)(Graph);

typedef struct funct{
    INITGRAPH init;
    ADDADJ addEdge;
    PRINT print;
}FunctGraph;

 typedef struct AdjList{  //I need this in order to use the adj as a List
    List *nodes;
}AdjList;

Graph.c

Graph initGraphList(int nodes_count){
    Graph G = malloc(sizeof(struct TGraph));
    ((AdjList *)(G->adj))->nodes = malloc(nodes_count * sizeof(List)); <<< PROBLEM HERE
    G->nodes_count = nodes_count;
    return G;
}

Graphparser.c

Graph parse(FILE *file, FunctGraph *F){   
    Graph G = NULL;
    puts("Controllo numero di nodi...");
    if (!match(file, LPAR)){     // Check if number of nodes is present
        syntax_error(errorsymb(LPAR), file);
    }else{
        fseek(file,1,SEEK_CUR);     //Going over the LPAR
        G = parse_init(file, F->init); //Initialize the Graph <<< PROBLEM HERE
        if (G == NULL){
            fprintf(stderr, "Errore nell'allocazione del grafo\n");
            exit(1);
        }else{
            if (!match(file, RPAR))
                syntax_error(errorsymb(RPAR), file);
            else{                    // If so parse the graph
                fseek(file,1,SEEK_CUR);
                printf("Rilevato grafo da %d nodi\n", G->nodes_count);
                puts("Costruisco il grafo...");
                while(!match(file, DOT)){
                    read_node(G, file, F->addEdge);
                }
            }
        }
    }
    return G; // return the parsed Graph
}

int match(FILE *file, type et)
{
    // Try to match symbol of expected type 'et' in file
    // [returns 1 if successful, 0 otherwise]
    char c;
    type rp;                       // Type of the symbol read
    int res=0;
    while(((c = fgetc(file)) == '\t') || (c == '\n') || (c == ' ')); // Skip intitial tabulation, newline and spaces
    switch(c) {        // Determine the read symbol type
        case ',':
            rp = COMMA; break;
        case '(':
            rp = LPAR; break;
        case ')':
            rp = RPAR; break;
        case '.':
            rp = DOT; break;
        case '-':
            rp = MINUS; break;
        case '>':
            rp = ARROW; break;
        case ';':
            rp = SEMICOL; break;
        default :
            rp = NODEID; break;
    }
    ungetc(c,file);   // Push the characters read back to the file
    if (rp==et)        // The expexted type et and the read symbol type rp match
        res = 1;
    return res;
}

Graph parse_init(FILE *file, INITGRAPH init){
    unsigned int nodes;
    fscanf(file, "%d", &nodes);
    if(nodes >= INT_MAX)
        syntax_error("Numero nodi troppo grande", file);
    return init(nodes); // Initialize the graph
}

我认为这应该是我们找到这个问题所需的所有代码。 正如我在代码中标记的那样,问题出在这一行:

((AdjList *)(G->adj))->nodes = malloc(nodes_count * sizeof(List));

这里调试器调用&#34;分段错误&#34;,但我不明白为什么。 你有什么想法为什么代码运行没有调试器而不是它,给出了这个错误? 提前感谢所有的帮助。

1 个答案:

答案 0 :(得分:2)

Graph G = malloc(sizeof(struct TGraph));
((AdjList *)(G->adj))->nodes = malloc(nodes_count * sizeof(List));

您为malloc分配了G的内存,但您从未使用有效值对其进行初始化,因此解除引用G->adj将导致未定义的行为。它似乎在发布中有效,但在调试版本中没有。

如果您使用的是Visual Studio,调试版本通常会使用(我认为0xFE或其他东西来初始化内存,因此当您取消引用指针时它会崩溃。在发布版本中,这不会发生,所以它有一些随机地址,显然不会造成任何直接问题。不确定gcc是否也会这样做。

您需要的是:

Graph G = malloc(sizeof(struct TGraph));
G->adj = malloc(whatever);
G->node_count = 0;
etc.
((AdjList *)(G->adj))->nodes = malloc(nodes_count * sizeof(List));