C中的队列分段错误

时间:2010-05-11 14:58:52

标签: c queue segmentation-fault

将结构添加到队列后,我收到以下代码的分段错误。

当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

5 个答案:

答案 0 :(得分:4)

我认为你的问题在于:

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

您按照结构的大小缩放next_index,但这是由第二个语句自动完成的 - *(queue + (next_index))相当于queue[next_index],后者对所有人都更具可读性但是我们这些自从K&amp; R以来一直使用C的人首次出版: - )

换句话说,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,是吗?

答案 1 :(得分:1)

您将next_index乘以sizeof(struct myInfo),这是不必要的。添加到指针类型时,将根据指向对象的大小自动计算偏移量。更改push()的第一行应该足够了:

int next_index = (queue_size + queue_head) % MAX_QUEUE;

答案 2 :(得分: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);
        }
}

答案 3 :(得分:0)

*(queue + (next_index)) = info;

queue是指向struct myInfo的指针。您只需要为其添加1即可获得下一个地址 - 您将其视为char *

你可以这样做:

*(queue + queue_size++) = info;

答案 4 :(得分: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 */
   }
}