2010-05-11 119 views
1

將結構添加到我的隊列後,出現以下代碼的分段錯誤。C中隊列出現分段錯誤

當MAX_QUEUE設置爲高電平時發生分段故障,但當設置爲低電平(100或200)時,不會發生錯誤。自從我上次用C語言編程以來,這已經有一段時間了,所以我希望有任何幫助。

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

#define MAX_QUEUE 1000 

struct myInfo { 
     char data[20]; 
}; 

struct myInfo* queue; 
void push(struct myInfo); 
int queue_head = 0; 
int queue_size = 0; 

int main(int argc, char *argv[]) 
{ 
     queue = (struct myInfo*) malloc(sizeof(struct myInfo) * MAX_QUEUE); 

     struct myInfo info; 
     char buf[10]; 
     strcpy(buf, "hello"); 

     while (1) 
     { 
       strcpy(info.data, buf); 
       push(info); 
     } 
} 

void push(struct myInfo info) { 
     int next_index = sizeof(struct myInfo) * ((queue_size + queue_head) % MAX_QUEUE); 
     printf("Pushing %s to %d\n", info.data, next_index); 
     *(queue + (next_index)) = info; 
     queue_size++; 
} 

輸出:

Pushing hello to 0 
Pushing hello to 20 
... 
Pushing hello to 7540 
Pushing hello to 7560 
Pushing hello to 7580 
Segmentation fault 
+0

隊列中,將它聲明爲'struct myInfo queue [MAXQUEUE]'和帶有'queue [next_index]''的表達式的引用元素可能更爲明智。雖然我在一段時間內還沒有用C語言編程。 – 2010-05-11 15:19:16

回答

4

我覺得你的問題就在這裏:

int next_index = sizeof(struct myInfo) * ... 
*(queue + (next_index)) = info; 

你縮放next_index你的結構的大小,但是這是一件由第二自動完成聲明 - *(queue + (next_index))相當於queue[next_index],後者對除我們之外的所有人都更易讀,因爲K & r爲首次發表:-)

換句話說,next_index值應當是一個從0MAX_QUEUE-1,所以嘗試改變的第一個語句由sizeof(struct myInfo)刪除乘法:

void push(struct myInfo info) { 
    int next_index = (queue_size + queue_head) % MAX_QUEUE; 
    printf("Pushing %s to %d\n", info.data, next_index); 
    queue[next_index] = info; 
    queue_size++; 
} 

而且牢記你最終會在你的無限循環中溢出queue_size。您大概會檢查以確保queue_size在最終生產就緒代碼中的增量不會超過MAX_QUEUE,是的?

+0

謝謝,那就是問題所在!是的,我有其他代碼用於檢查queue_size並在隊列滿時發出警報。在這種情況下,這不是一個因素,所以我沒有包括它。 :) – Trevor 2010-05-11 15:19:29

0
void push(struct myInfo info) { 
     int next_index = (queue_size + queue_head) % MAX_QUEUE; 
     printf("Pushing %s to %d\n", info.data, next_index); 
     queue[next_index] = info; 
     queue_size++; 
} 

而且,你並不需要該臨時buf

int main(int argc, char *argv[]) 
{ 
     queue = (struct myInfo*) malloc(sizeof(struct myInfo) * MAX_QUEUE); 

     while (1) 
     { 
       struct myInfo info; /* Seems you're using C99 so we can declare here */ 
       strcpy(info.data, "hello"); 
       push(info); 
     } 
} 
1

你被sizeof(struct myInfo)乘以next_index,這是沒有必要的。添加到指針類型時,偏移量將根據指向對象的大小自動計算。改變push()第一行應足以:

int next_index = (queue_size + queue_head) % MAX_QUEUE; 
0
*(queue + (next_index)) = info; 

queue是指向一個struct myInfo。您只需要添加1即可獲取下一個地址 - 您將其視爲char *

你可以這樣做:

*(queue + queue_size++) = info; 
+0

不,您不能:隊列是循環的,並從數組內的索引'queue_head'開始。 – Thomas 2010-05-11 15:13:59

0

你可以把隊列作爲一個數組,然後它應該是簡單的推項目:由於您使用的靜態大小

 
void push(struct myInfo info) { 
    if (queue_size < MAX_QUEUE) { 
    printf("Pushing %s to %d\n", info.data, queue_size); 
    queue[queue_size] = info; 
    queue_size++; 
    } else { 
    printf("ERROR: Queue is full.\n"); 
    /* alternatively you could have a queue_insertion_point 
     variable to keep track of where you are in the queue 
     and use that as your index into your array. You'd then 
     reset it to 0 (to wrap around) when it hit MAX_QUEUE. 
     You need to ensure you don't overwrite data currently 
     in the queue by comparing it against queue_head */ 
    } 
}