2013-04-16 63 views
1

我正在處理C中的一個List實例,其中新節點被推到堆棧的末尾。當我嘗試將新節點推到最後時,我不斷收到Bus Error: 10。這裏是我的推送功能:總線錯誤:在處理結構指針的C中爲10

void push(struct node *tail, struct node *newNode) { 

tail->next = newNode; // gdb says the problem is here 
tail = tail->next; 

} 

,我把它用push(tail, newNode);

而且,這裏是我的結構,如果必要的:

struct node 
{ 
    int hour; 
    int minute; 
    char *name; 
    struct node *next; 
}; 

,這裏是展示代碼的主要功能,導致push()

int main() 

{ 
char inputString[50]; 
int timeHour, timeMin; 
struct node *head; 
struct node *tail; 

while ((scanf("%d:%d", &timeHour, &timeMin)) != EOF) { 
    scanf("%s", inputString); 

    if (strcmp(inputString, "enqueue") == 0) { 
     if (head == NULL) { 
      head = malloc(sizeof(struct node)); 

      head->hour = timeHour; 
      head->minute = timeMin; 

      // get name 
      scanf("%s", inputString); 
      head->name = malloc(strlen(inputString)+1); 
      strcpy(head->name, inputString); 

      tail = head; 

      printEnqueue(head); 
     } else { 
      struct node *newEntry = malloc(sizeof(struct node)); 

      newEntry->hour = timeHour; 
      newEntry->minute = timeMin; 

      // get name 
      scanf("%s", inputString); 
      newEntry->name = malloc(strlen(inputString)+1); 
      strcpy(newEntry->name, inputString); 

      push(tail, newEntry); 

      printEnqueue(newEntry); 
     } 
    } else { 
     pop(&head, timeHour, timeMin); 
    } 
} 

return 0; 
} 
+1

爲什麼你傳遞一個指針的指針'newNode'到函數?你不修改指向'newNode'的指針,所以你只需要傳入指針。另外,當你在調試器中進入它時,* newNode指向什麼?它是一個有效的節點嗎? – user1118321

+0

將'newNode'改爲常規指針後,我知道它在gdb中指向'newNode = 0x100103920'。我對存儲器一無所知,所以我不確定這是否是有效的節點或者不是哈哈。 – Slayter

+2

最小的,**可編譯的**測試用例,請。沒有猜測,我們沒有所有必要的信息來回答這個問題。 – Sebivor

回答

2

我懷疑headtail節點在main函數沒有正確初始化。

從您的代碼看來,head將被分配一個新節點,如果它是NULL。然而,你的head定義並不保證它的最初NULL(同樣沒有tail)。所以你可以繞過if (head == NULL)分支(請確保它們確實從gdb請:))。

Bus error很少見。所以我GOOGLE了它,並從here,可能發生總線錯誤時

using a processor instruction with an address that does not satisfy its alignment requirements.

這可能是因爲tail未對齊和代碼直接通往else分支。因此, push(tail, newEntry);將訪問未對齊的尾部(這也驗證了我的嫌疑犯)。

+0

這是它的日程!謝謝。 – Slayter

+1

@Slayter np。所以下一次,請記住在定義變量時明確初始化。 :p –

+0

是的,我的印象是,當聲明類似的東西時,它默認爲NULL。但我想這更像是一個面向對象的東西? – Slayter

1

修正#3:while ((scanf("%d:%d", &timeHour, &timeMin)) != EOF)在這個循環體內,不能保證這兩個整數分別爲timeHourtimeMin。也許你的意思是while ((scanf("%d:%d", &timeHour, &timeMin)) == 2)


修訂#2:當你傳遞一個值的函數,你傳遞的,不是變量。您在push內對tail所做的任務對於主叫方(您的main)不可見。您需要傳入一個指向該變量的指針(例如,&head這是一個struct node **),並將其指定爲以前的*tail。或者,您可以從push中獲得return newNode;,並將返回值用作新的head


修訂:這甚至不會看起來會編譯。我們來看看push

void push(struct node **tail, struct node *newNode) { 
    (*tail)->next = *newNode; // gdb says the problem is here 
    *tail = (*tail)->next; 
} 

什麼是*newNodestruct node。 什麼是(*tail)->next的類型?這就是在這個片斷:

struct node 
{ 
    int hour; 
    int minute; 
    char *name; 
    struct node *next; 
}; 

解決您的不一致性,並確保您最小,編譯測試用例是編譯您發佈之前。


不要忘記檢查返回值scanf!在你的情況下,它應該返回1,除非發生錯誤。


 head->name = malloc(strlen(inputString)); 
     strcpy(head->name, inputString); 

這是錯誤的,因爲你沒有分配足夠的空間來存儲'\0'字符。我想你的意思是malloc(strlen(inputString) + 1)。代碼中有兩個此錯誤的實例。我不打算重複自己。


 struct node *newEntry = malloc(sizeof(struct node)); 
     push(&tail, newEntry); 

什麼的newEntry類型? struct node *

 void push(struct node **tail, struct node **newNode) 

什麼是newNode的類型? struct node **。你看到不一致嗎?你需要在struct node **通過,但newEntrystruct node *

+0

抱歉,我在將'struct node * newNode'更改爲單個指針後忘記了更改我的問題。在向'strlen(inputString)'添加+1後,它仍然會產生總線錯誤。 – Slayter

+0

@Slayter我更新了我的答案以符合您的修改。 – Sebivor

+0

@Slayter如果您要再次更新您的問題,請確保您將malloc修補程序添加到它並確保它編譯。 – Sebivor

1

變化

void push(struct node *tail, struct node *newNode) 
{ 
    tail->next = newNode; // gdb says the problem is here 
    tail = tail->next; 
} 

void push(struct node **tail, struct node *newNode) 
{ 
    (*tail)->next = newNode; // gdb says the problem is here 
    (*tail) = (*tail)->next; 
} 

然後調用它,而不是

push(&tail, newEntry); 

因爲你擁有它目前 '尾巴' 將永遠不會改變,因爲你不及格變量的地址給函數,所以你不能改變它指向的內容。

也確保您初始化您的所有本地變量(標題,尾部,...),使其成爲一種習慣

+0

這實際上是它原來的樣子,但是因爲別人的推薦而改變了它。這是應該的,但真正的問題在其他地方。 – Slayter