2013-08-27 68 views
0

這裏是兩個C程序來實現以簡單的形式隊列數據結構單個隊列和多個隊列使用同一程序不能工作

  • 第一:

    限定一個隊列,它的工作完全

  • 第二個:

    定義了多個隊列,它在執行時崩潰

功能都在這兩個程序除了main()是實施 同樣是不同的一點。

所以這裏的問題:爲什麼第二個代碼不工作?

*這裏是代碼*

代碼1:

/* 
Single queue -- this work perfectly 
*/ 
#include <stdio.h> 
#define Q_MAX_SIZE 255 

struct queue { 
    int* pointer; 
    int* currentValue; 
    int max, count, theQueue[Q_MAX_SIZE]; 
}; 

//prototyps 
void initQueue(struct queue*); 
unsigned short pushQueue(struct queue*, int); 
int* popQueue(struct queue*); 

int main(void) { 
    int j; 
    struct queue q; 

    initQueue(&q); 

    for (j = 0; j < 6; j++) 
     pushQueue(&q, j); 

    int* inputobj = popQueue(&q); 
    while (inputobj != NULL) 
    { 
     printf("%d ", *inputobj); 
     inputobj = popQueue(&q); 
    } 

    printf("\n\ndone..Queue is empty\n"); 

    return 0; 
} 

//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 

void initQueue(struct queue *Q) 
{ 
    Q->pointer = Q->theQueue; 
    Q->max = Q_MAX_SIZE; 
    Q->count = 0; 
} 

unsigned short pushQueue(struct queue *Q, int input) { 
    if (Q->count < Q->max) 
    { 
     *Q->pointer = input; 
     Q->pointer++; 
     Q->count++; 
     return 1; 
    } 
    else 
     return 0; 
} 

//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 

int* popQueue(struct queue *Q) { 
    int i; 
    if (Q->count > 0) 
    { 

     *Q->currentValue = *Q->theQueue; 
     Q->pointer--; 
     Q->count--; 

     for (i = 0; i < Q->count; i++) 
     { 
      int* currentPtr = Q->theQueue + i; 
      int* nextPtr = currentPtr + 1; 
      *currentPtr = *nextPtr; 
     } 

     return Q->currentValue; 
    } 
    else 
     NULL; 
} 

代碼2:

/* 
Multiple queues -- this not work and crash at execution 
*/ 
#include <stdio.h> 
#define Q_MAX_SIZE 255 

struct queue { 
    int* pointer; 
    int* currentValue; 
    int max, count, theQueue[Q_MAX_SIZE]; 
}; 

//prototyps 
void initQueue(struct queue*); 
unsigned short pushQueue(struct queue*, int); 
int* popQueue(struct queue*); 

int main(void) { 
     int i, j; 
    struct queue obj[5]; 

    for(i=0; i<5; i++) 
    { 
     initQueue(&obj[i]); 

     for(j = 0; j<3; j++) 
     { 
      pushQueue(&obj[i], j); 
     } 
    } 

    for(i=0; i<5; i++) 
    { 
     printf("Queue[%d]:\n", i); 
     int* inputobj; 
     inputobj = popQueue(&obj[i]); 

     while(inputobj != NULL) 
     { 
      printf("Queue[No.%d] = %d\n", i, *inputobj); 
      inputobj = popQueue(&obj[i]); 
     } 
     putchar('\n'); 
    } 

    return 0; 
} 

//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 

void initQueue(struct queue *Q) 
{ 
    Q->pointer = Q->theQueue; 
    Q->max = Q_MAX_SIZE; 
    Q->count = 0; 
} 

unsigned short pushQueue(struct queue *Q, int input) { 
    if (Q->count < Q->max) 
    { 
     *Q->pointer = input; 
     Q->pointer++; 
     Q->count++; 
     return 1; 
    } 
    else 
     return 0; 
} 

//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 

int* popQueue(struct queue *Q) { 
    int i; 
    if (Q->count > 0) 
    { 

     *Q->currentValue = *Q->theQueue; 
     Q->pointer--; 
     Q->count--; 

     for (i = 0; i < Q->count; i++) 
     { 
      int* currentPtr = Q->theQueue + i; 
      int* nextPtr = currentPtr + 1; 
      *currentPtr = *nextPtr; 
     } 

     return Q->currentValue; 
    } 
    else 
     NULL; 
} 

更新:問題是initQueue()和它的通過爲Q->currentValue分配內存 解決這裏是編輯後的功能:

void initQueue(struct queue *Q) 
{ 
    Q->currentValue = malloc(sizeof(int)); 
    Q->pointer = Q->theQueue; 
    Q->max = Q_MAX_SIZE; 
    Q->count = 0; 
} 
+4

學習如何使用debbuger,看看發生了什麼事情 –

+0

我的猜測是,你要訪問這樣的:initQueue(&(OBJ [1])); – Jiminion

+0

@Jim我做了你說的,但它不是工作 –

回答

3

由於這兩個答案已經說明,問題是Q->current_value從來沒有被賦予一個值,所以它指向一個未定義的地址和每一個解除引用如*Q->currentValue = ..是未定義的行爲。代碼1似乎有效的事實並不能證明其他任何事情,因爲由於UB的性質,沒有行爲得到保證,你的程序可能會或可能不會崩潰(或者你的狗可能會爆炸,龍會飛出你的鼻子......): - ))

當然有多種解決方案,都意味着不同的東西:

  1. 如果currentValue應該只持有一定值的副本,也可能是int currentValue而不是int *...和assignnment將

    Q-> currentValue = * Q-> theQueue;

    和return語句將是return &Q->currentValue。在這種情況下,你會返回一個指針的theQueue[0]

  2. 值,如果你想點的位置在theQueue,吉姆的雁告訴正確的方法:

    Q-> CurrentValue的= Q- > theQueue;

    在你yould返回一個指針的theQueue[0]值(這可能是你不想要的東西)

  3. 你可以分配內存以Q->currentValuemalloc(sizeof (int));,然後離開賦值爲這種情況下,它是。在這種情況下,你會返回一個指針的theQueue[0]值就像在(1)

+0

@lngo Leonhardt謝謝我理解第1和第2點,但是對於第3點,我對將malloc(sizeof(int));'in'initQueue()'或'popQueue()'放在哪裏感到困惑? ...再次感謝:) –

+1

Q-> currentValue = malloc(sizeof(int));把它放在InitQueue()例程中。 – Jiminion

+0

@Jim它現在的工作,現在當我分配內存的'Q-> currentValue'在'code2'initQueue' ...謝謝先生吉姆 –

0

位置Q-> CurrentValue的無法訪問,這就是問題所在。它沒有分配。

的解決方案是在init程序分配內存的右邊部分:

Q = malloc(sizeof(struct queue)); 

或許還初始化後,你的所有變量的值。

+0

嗨@MatteoD我做了你說的,但它沒有工作在這裏是編輯後的initQueue [http://codepad.org/aISEmUTk] –

+0

我可以不打開鏈接。 – darmat

+0

對不起@MatteoD這裏是鏈接[http://codepad.org/aISEmUTk] –

1

這實際上是非常微妙的問題,我認爲。這個問題(我認爲)是popqueue這一行():

*Q->currentValue = *Q->theQueue; 

我反覆檢查和您最初的代碼(沒有數組)也賽格故障。它不像你所說的那樣工作。你應該寫:

Q->currentValue = Q->theQueue; 

C可與指針有點理解和適當分配的事情,但是當你添加了另一個級別(陣列),我覺得任務被迫到的東西,沒有工作。這是我的承擔。我想我會提出一個賞金,讓你可以得到更好的答案。

1

首先,我不會試圖把這樣的代碼一個生產。事情可以做得更簡單,更清晰,更高效,更不容易出錯。

我已經通過在儘可能少的地方改變東西來「固定」你的程序。必須清楚的是,這不會讓事情更優雅。只有重新思考和重寫才能讓事情更加優雅。

你有錯誤(包括第一個和第二個程序)是例行的popQueue。

  1. 你在else子句中什麼也不返回。你應該「返回NULL」。這至少是拙劣的編程。

  2. 例程返回隊列中的1 2 3 4 5 5和1 2 2。這是因爲Q-> CurrentValue指向theQueue數組中的第一個位置,並且您將所有值向上移位。這意味着CurrentValue事實上指向下一個值。

解決方案(再次:這是不優雅,我也不會把它在生產,但它以最小的變化原件)到你的問題是:

  1. 變化的結構(持有真正的CurrentValue的)

    struct queue 
    { 
        int* pointer; 
        int currentValue; 
        int max, count, theQueue[Q_MAX_SIZE]; 
    }; 
    
  2. 更改常規popQueue

    int* popQueue(struct queue *Q) { 
        int i; 
        if (Q->count > 0) 
        { 
    
         Q->currentValue = *Q->theQueue; 
         Q->pointer--; 
         Q->count--; 
    
         for (i = 0; i < Q->count; i++) 
         { 
          int* currentPtr = Q->theQueue + i; 
          int* nextPtr = currentPtr + 1; 
          *currentPtr = *nextPtr; 
         } 
    
         return &(Q->currentValue); 
        } 
        else 
         return NULL; 
    } 
    

親切的問候, PB

+0

感謝您的澄清,你不添加任何新的東西** Jim **和** Ingo-leonhardt **說..無論如何,我得到的問題是謝謝大家 –

相關問題