代码之家  ›  专栏  ›  技术社区  ›  Trevor

C语言中带队列的分段错误

  •  1
  • Trevor  · 技术社区  · 16 年前

    在将结构添加到队列中后,以下代码出现分段错误。

    #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 回复  |  直到 16 年前
        1
  •  4
  •   paxdiablo    16 年前

    我认为你的问题在于:

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

    你在缩放 next_index 但这是由第二个语句自动完成的- *(queue + (next_index)) 相当于 queue[next_index]

    换句话说, 下一个索引 应为中的值 0 到 MAX_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 在你的无限循环中。你大概会检查以确保 队列大小

        2
  •  1
  •   JSBÕ±Õ¸Õ£Õ¹    16 年前

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

    int next_index = (queue_size + queue_head) % MAX_QUEUE;
    
        3
  •  0
  •   Thomas    16 年前
    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);
            }
    }
    
        4
  •  0
  •   tomlogic    16 年前
    *(queue + (next_index)) = info;
    

    queue 是指向 struct myInfo . 你只需要在上面加1就可以得到下一个地址——你把它当作一个 char *

    你可以这样做:

    *(queue + queue_size++) = info;
    
        5
  •  0
  •   smountcastle    16 年前

    你可以请客 队列 作为一个数组,然后推送项目应该很简单:

    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 */
       }
    }