[英]Segmentation fault with queue in C
I am getting a segmentation fault with the following code after adding structs to my queue. 在将结构添加到队列后,出现以下代码的分段错误。
The segmentation fault occurs when the MAX_QUEUE is set high but when I set it low (100 or 200), the error doesn't occur. 当MAX_QUEUE设置为高电平时发生分段错误,但是当我将其设置为低电平(100或200)时,不会发生错误。 It has been a while since I last programmed in C, so any help is appreciated.
自从我上一次用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++;
}
Output: 输出:
Pushing hello to 0
Pushing hello to 20
...
Pushing hello to 7540
Pushing hello to 7560
Pushing hello to 7580
Segmentation fault
I think your problem lies here: 我认为您的问题出在这里:
int next_index = sizeof(struct myInfo) * ...
*(queue + (next_index)) = info;
You're scaling next_index
by the size of your structure but this is something done automatically by that second statement - *(queue + (next_index))
is equivalent to queue[next_index]
and the latter is more readable to all but those of us who have been using C since K&R was first published :-) 您正在按结构的大小缩放
next_index
,但这是第二条语句自动完成的操作- *(queue + (next_index))
等价于queue[next_index]
,后者对我们所有人(除我们之外的所有人)更易读自K&R首次发布以来一直使用C :-)
In other words, next_index
should be a value from 0
to MAX_QUEUE-1
, so try changing the first statement to remove the multiplication by sizeof(struct myInfo)
: 换句话说,
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++;
}
And keep in mind that you'll eventually overflow queue_size
in that infinite loop of yours. 请记住,您最终将在自己的无限循环中溢出
queue_size
。 You will presumably be checking to ensure that queue_size
is not incremented beyond MAX_QUEUE in the final production-ready code, yes? 您大概会检查以确保在最终的生产就绪代码中,
queue_size
不会增加到超过MAX_QUEUE,是吗?
You're multiplying next_index
by sizeof(struct myInfo)
, which isn't necessary. 您将
next_index
乘以sizeof(struct myInfo)
,这是不必要的。 When you add to a pointer type, the offset is automatically calculated in terms of the size of the pointed-to object. 添加到指针类型时,将根据指向的对象的大小自动计算偏移量。 Changing the first line of
push()
should be sufficient: 更改
push()
的第一行应该足够了:
int next_index = (queue_size + queue_head) % MAX_QUEUE;
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++;
}
Also, you don't need that temporary buf
: 另外,您不需要该临时
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);
}
}
*(queue + (next_index)) = info;
queue
is a pointer to a struct myInfo
. queue
是指向struct myInfo
的指针。 You only need to add 1 to it to get the next address -- you're treating it like a char *
. 您只需要向其添加1即可获得下一个地址-您将其像
char *
一样对待。
You can just do: 您可以这样做:
*(queue + queue_size++) = info;
You can treat queue as an array and then it should be simple to push items: 您可以将队列视为数组,然后将项目推入应该很简单:
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 */ } }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.