2013-08-27 42 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 **说..无论如何,我得到的问题是谢谢大家 –

相关问题