gpt4 book ai didi

c - 队列返回的指针不能在没有段错误的情况下被取消引用

转载 作者:太空宇宙 更新时间:2023-11-04 07:49:27 24 4
gpt4 key购买 nike

我正在尝试编写一个队列。为了对其进行测试,我将几个值排入队列,这些值是指向静态分配的堆栈变量的指针。当我打印出已推送的堆栈变量的地址和出队返回的指针(对应于该项目的原始入队)时,我得到的地址似乎是相同的。当我取消引用指向静态分配变量的指针(我使用 & 运算符内联创建的指针)时,它会打印出我期望的值 10。但是当我引用 dequeue 返回的指针时,它似乎是相同的地址,这将出现段错误。我不太确定发生了什么,我对 C 内存模型的理解无法解释这一点。

输出

Storing item at index 0
Queue (head, tail) = 0, 1
1158904628, 0, 0,
Storing item at index 1
Queue (head, tail) = 0, 2
1158904628, 1158904632, 0,
Storing item at index 2
Queue (head, tail) = 0, 0
1158904628, 1158904632, 1158904636,
---------------------------
Enqueued pointer: 45137b34
Enqueued pointer value: 10
Queue (head, tail) = 1, 0
0, 1158904632, 1158904636,
Dequeued pointer: 45137b34
Segmentation fault (core dumped)

编译gcc -o main queue.c

代码

#include <stdio.h>
#include <stdlib.h>

typedef struct {
int *buffer;
int size;
int capacity;
int head;
int tail;
} Queue;

void queue_init(Queue *queue, int capacity) {
void *ptr = malloc((sizeof(void*)) * capacity);
queue->buffer = ptr;
queue->capacity = capacity;
queue->size = 0;
queue->head = 0;
queue->tail = 0;
}

void* queue_dequeue(Queue *queue) {
if (queue->size == 0) return NULL;

void *item = queue->buffer[queue->head];
queue->buffer[queue->head] = NULL;
queue->head = (queue->head + 1) % queue->capacity;
printf("Queue (head, tail) = %d, %d\n", queue->head, queue->tail);
queue->size--;

for (int i = 0; i < 3; i++) {
printf("%u, ", queue->buffer[i]);
}
printf("\n");
return item;
}

int queue_enqueue(Queue *queue, void *item) {
if (queue->size == queue->capacity) return -1;

printf("Storing item at index %d\n", queue->tail);
queue->buffer[queue->tail] = item;
queue->size++;
queue->tail = (queue->tail + 1) % queue->capacity;
printf("Queue (head, tail) = %d, %d\n", queue->head, queue->tail);

for (int i = 0; i < 3; i++) {
printf("%u, ", queue->buffer[i]);
}
printf("\n");
}

int main() {
int a = 10;
int b = 20;
int c = 30;

Queue q;
queue_init(&q, 3);
queue_enqueue(&q, &a);
queue_enqueue(&q, &b);
queue_enqueue(&q, &c);
printf("---------------------------\n");

int *org = &a;
int *ptr;
printf("Enqueued pointer: %x\n", org);
printf("Enqueued pointer value: %i\n", *org);
ptr = queue_dequeue(&q);
printf("Dequeued pointer: %x\n", ptr);
printf("Dequeued pointer value: %i\n", *ptr);

return 0;
}

最佳答案

需要将int *改为void **
否则整数空间(4bytes)不足以保存void*(8bytes)
修改如下

#include <stdio.h>
#include <stdlib.h>

typedef struct {
void **buffer;
int size;
int capacity;
int head;
int tail;
} Queue;

void queue_init(Queue *queue, int capacity) {
void *ptr = malloc((sizeof(void*)) * capacity);
queue->buffer = ptr;
queue->capacity = capacity;
queue->size = 0;
queue->head = 0;
queue->tail = 0;
}

void* queue_dequeue(Queue *queue) {
if (queue->size == 0) return NULL;

void *item = queue->buffer[queue->head];
queue->buffer[queue->head] = NULL;
queue->head = (queue->head + 1) % queue->capacity;
printf("Queue (head, tail) = %d, %d\n", queue->head, queue->tail);
queue->size--;

for (int i = 0; i < queue->size; i++) {
printf("%p, ", queue->buffer[i]);
}
printf("\n");
return item;
}

int queue_enqueue(Queue *queue, void *item) {
if (queue->size == queue->capacity) return -1;

printf("Storing item at index %d\n", queue->tail);
queue->buffer[queue->tail] = item;
queue->size++;
queue->tail = (queue->tail + 1) % queue->capacity;
printf("Queue (head, tail) = %d, %d\n", queue->head, queue->tail);

for (int i = 0; i < queue->size; i++) {
printf("%p, ", queue->buffer[i]);
}
printf("\n");
return 0;
}

int main() {
int a = 10;
int b = 20;
int c = 30;

Queue q;
queue_init(&q, 3);
queue_enqueue(&q, &a);
queue_enqueue(&q, &b);
queue_enqueue(&q, &c);
printf("---------------------------\n");

int *org = &a;
int *ptr;
printf("Enqueued pointer: %p\n", org);
printf("Enqueued pointer value: %i\n", *org);
ptr = queue_dequeue(&q);
printf("Dequeued pointer: %p\n", ptr);
printf("Dequeued pointer value: %i\n", *ptr);

return 0;
}

关于c - 队列返回的指针不能在没有段错误的情况下被取消引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54759272/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com