我在構建一個用圖形做各種事情的程序時遇到了這個問題。 我使用代碼塊在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;
}
Gra phparser.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));
這裏的調試器調用「段錯誤」,但我不明白爲什麼。 你有沒有任何想法,爲什麼代碼運行沒有調試器,而不是它,給出了這個錯誤? 在此先感謝您的幫助。
我試圖用你的建議分配是這樣的:「G->因爲想在稍後將其轉換爲'AdjList *' 調試器不會調用在那裏停下來,但是當試圖訪問列表的元素時,我收到另一個「分段錯誤」。 我認爲我的分配仍然存在問題。 – Aster
@Baum 問題是我必須創建一個Graph結構,它可以支持列表和鄰接矩陣,爲了做到這一點,老師教我們使用'void *'指針,以便將該元素與任何一種方法。 有沒有辦法確保'G-> adj'是否指向一個有效的'AdjList'(或'AdjMatrix')對象? 當然,感謝你們雙方在你身邊幫助我。 – Aster
你必須分配足夠的空間,以便爲結構中的較大結構保留所需數量的元素。爲了使它更易於維護,聯合可能是一個好主意,因爲那樣你可以根據需要在任何元素上添加元素而不需要投射它,而且sizeof也會給你正確的尺寸。 – Devolus