C中队列出现分段错误
将结构添加到我的队列后,出现以下代码的分段错误。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
我觉得你的问题就在这里:
int next_index = sizeof(struct myInfo) * ...
*(queue + (next_index)) = info;
你缩放next_index
你的结构的大小,但是这是一件由第二自动完成声明 - *(queue + (next_index))
相当于queue[next_index]
,后者对除我们之外的所有人都更易读,因为K & r为首次发表:-)
换句话说,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
。您大概会检查以确保queue_size
在最终生产就绪代码中的增量不会超过MAX_QUEUE,是的?
谢谢,那就是问题所在!是的,我有其他代码用于检查queue_size并在队列满时发出警报。在这种情况下,这不是一个因素,所以我没有包括它。 :) – Trevor 2010-05-11 15:19:29
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);
}
}
你被sizeof(struct myInfo)
乘以next_index
,这是没有必要的。添加到指针类型时,偏移量将根据指向对象的大小自动计算。改变push()
第一行应足以:
int next_index = (queue_size + queue_head) % MAX_QUEUE;
*(queue + (next_index)) = info;
queue
是指向一个struct myInfo
。您只需要添加1即可获取下一个地址 - 您将其视为char *
。
你可以这样做:
*(queue + queue_size++) = info;
不,您不能:队列是循环的,并从数组内的索引'queue_head'开始。 – Thomas 2010-05-11 15:13:59
你可以把队列作为一个数组,然后它应该是简单的推项目:由于您使用的静态大小
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 */ } }
队列中,将它声明为'struct myInfo queue [MAXQUEUE]'和带有'queue [next_index]''的表达式的引用元素可能更为明智。虽然我在一段时间内还没有用C语言编程。 – 2010-05-11 15:19:16