2016-09-28 90 views
-1

對不起,如果這已經被問過無數次,但我想我已經理解的字符串(字符數組)如何在C段錯誤調用結構

工作,在我的程序有問題,我的成員時「堆棧」結構,它看起來像這樣(在stack.h):

struct stack_t { 
/* Stack-Datentyp */ 
/* Stacks have a head-node, a length, and a name. 
Stacks are filled with links (nodes) that are defined below. These links have 
a generic data pointer and a pointer to the next link */ 
link head;      
unsigned int length;    
char *name;      //stack name 
}; 

typedef struct stack_t *stack; 
在我的main.c

,我稱之爲叫「stack_new」功能,這似乎正常工作,因爲所有的printf通話工作:

stack stack_new(char *stackname) { 
    /* creates a new, empty stack */ 
stack st = (stack)(malloc(sizeof(stack))); 
if (st == NULL) { 
fprintf(stderr, "Error: Memory for Stack could not be allocated!\n"); 
return NULL; 
} 
st->head = NULL; 
printf("head works.\n"); 
st->length = 0; 
printf("length works.\n"); 
st->name = stackname; 
printf("stackname works.\n"); 
return st; 
} 

現在,當我在main.c中調用此函數時,出現seg故障。這是電話:

if (strcmp(input,"newstack") == 0) { 
    printf("Please enter stackname:\n"); 
    scanf("%s", &stackname); 
    printf("Debug: Input works.\n"); 
    stacklist[NumberOfStacks] = stack_new(stackname); 
    printf("stack created works-\n"); 
    NumberOfStacks++; 
    printf("A new stack with the name '%s' was created!\nIt is number %d in stack list.", stacklist[NumberOfStacks]->name, NumberOfStacks); 
    continue; 
} 

當我嘗試打印struct stacklist [NumberOfStacks]指向的成員名稱時發生seg故障。我在這裏做錯了什麼?

我還弄了一堆,告訴我關於我的stackname scanf的期望如何不同類型的警告:

警告:格式「%s」的期望類型的參數「字符」,但爭論2 'char()[50]'[-Wformat =] scanf(「%s」,& stackname);

我得到的其他警告告訴我,我沒有從我用於堆棧節點中的數據存儲的虛空指針中進行類型轉換,但我不認爲這與我的問題有關。

謝謝你的幫助!

編輯: 問題是我在將NumberOfStacks用作打印保存在數組中的結構成員的索引之前遞增了NumberOfStacks。

NumberOfStacks++; 
    printf("A new stack with the name '%s' was created!\nIt is  number %d in stack list.", stacklist[NumberOfStacks]->name, NumberOfStacks); 

這部分程序現在工作正常,謝謝!

+3

'棧ST =(堆)(malloc的(的sizeof(堆)));' - >'棧ST = malloc的(的sizeof(* ST ));' – BLUEPIXY

+2

'stacklist [NumberOfStacks] - > name':'stacklist [NumberOfStacks]'可能是未初始化的。因爲它增加到這之前('NumberOfStacks ++;') – BLUEPIXY

+0

對不起,我錯了。它仍然不工作,相同的分段錯誤。 NumberOfStacks已初始化(0)。我改變了malloc,它仍然是錯誤的。 – mneumann

回答

1

代碼中有幾個錯誤。評論中大多數都已經提到。我做了更正,似乎沒有段錯誤。 修改通過代碼中的註釋表示。

這是我結束了的代碼:

#include <stdio.h> 
// Prototype for malloc 
#include <stdlib.h> 
// Prototype for strdup 
#include <string.h> 

typedef void *link; /* Added to make it compile - you may have a different definition in your code */ 

struct stack_t { 
    /* Stack-Datentyp */ 
    /* Stacks have a head-node, a length, and a name. 
    * Stacks are filled with links (nodes) that are defined below. 
    * These links have 
    * a generic data pointer and a pointer to the next link */ 
    link head; 
    unsigned int length; 
    char *name;      //stack name 
}; 

typedef struct stack_t *stack; 

stack stack_new(char *stackname) { 
    /* creates a new, empty stack */ 
    stack st = malloc(sizeof(*st)); // changed to use the variable name 
    if (st == NULL) { 
     fprintf(stderr, "Error: Memory for Stack could not be allocated!\n"); 
     return NULL; 
    } 
    st->head = NULL; 
    printf("head works.\n"); 
    st->length = 0; 
    printf("length works.\n"); 
    st->name = strdup(stackname); // Changed: Duplicate the name so it won't get overwritten when creating the next stack 
    printf("stackname works.\n"); 
    return st; 
} 


int main(void) 
{ 
    char stackname[50];  // Added declaration for stackname. 
    stack stacklist[50];  // Added declaration. Can handle up to 50 stacks. 
    int NumberOfStacks = 0; 

    printf("Please enter stackname:\n"); 
    scanf("%s", stackname);    // Changed. Removed the "&" since stackname is a char*. 
    printf("Debug: Input works.\n"); 
    stacklist[NumberOfStacks] = stack_new(stackname); 
    printf("stack created works-\n"); 
    // All data is at index 0, so cannot use increased value of NumberOfStacks to get get the data. Also changed the text to "has index" since a 0 will be printed for stacknumber. 
    printf("A new stack with the name '%s' was created!\nIt has index %d in stack list.\n", stacklist[NumberOfStacks]->name, NumberOfStacks); 
    NumberOfStacks++; // Moved this line down. 
    return 0; 
} 
+0

非常感謝!我已經整合了您提出的所有更改,並且現在可以使用。問題是我的增加,你改變了它的位置。 – mneumann

0

對於警告,scanf正在等待類型'指向char'的指針。你的變量'stackname'被聲明爲'char stackname [50]'(我想你沒有發佈聲明)。 使用& stackname表示您想訪問數組的地址。使用堆棧名或堆棧名幾乎相同,因爲在第一種情況下,數組將被轉換爲指向數組的第一種情況的指針,在第二種情況下,它將是數組的地址,這是第一種情況的陣列。

如果你想複製一個字符串,你必須分配一個字符串大小的緩衝區(使用malloc)並使用strcpy。

對於段錯誤,向我們展示stacklist和NumberOfStacks的聲明。原因可能是NumberOfStacks的值大於數組的大小。

+0

謝謝你的提示。我的聲明如下: 'unsigned int exit = 0,NumberOfStacks = 0;' 'unsigned int MAXSTACKS = 50;' 'stack stacklist [MAXSTACKS]; (j = 0; j mneumann

+0

_如果你想複製一個字符串,你必須分配一個字符串大小的緩衝區(使用malloc),並使用strcpy._ 如果這是我的錯誤,創建一個新的堆棧時不會得到一個段錯誤,因爲字符串的內存沒有分配? 'st-> name = stackname' 無法正常工作,在這種情況下我必須使用strcpy嗎? – mneumann

+1

@mneumann既然你需要分配內存和複製數據,'st-> name = strdup(stackname)'將是一個不錯的選擇。 –