我正在研究我在C上的第一个程序,它涉及两个进程通信。从一个进程发送到另一个进程的消息长度可能不同,我需要存储它们直到接收方进程需要它。我认为使用FIFO结构会很好,长度可以变化,所以我决定编程。这是代码:
#include <stdio.h>
#include <stdlib.h>
typedef struct Queue{
int length;
struct Member *first;
struct Member *last;
}Queue;
typedef struct Member{
char ch;
struct Member *next;
}Member;
Queue create(){
struct Queue cola;
cola.length = 0;
return cola;
}
void add(struct Queue *q, char c){
if(q->length == 0){
struct Member m;
m.ch = c;
q->first = &m;
q->last = &m;
}else{
struct Member m;
m.ch = c;
q->last->next = &m;
q->last = &m;
}
q->length++;
}
void print(struct Queue n){
struct Member *p;
p = n.first;
for(int i = n.length; i > 0; i--){
printf("%c,", p->ch);
p = p->next;
}
printf("\n");
}
int main(){
struct Queue cola = create();
add(&cola, 'a');
printf("%c\n",cola.first->ch);
printf("%c\n",cola.last->ch);
print(cola);
}
问题在于,首先,当我尝试打印队列时,它不能按预期工作(我不知道它是print()函数还是结构本身的问题),但这是我可以自己找到的东西。最大的问题,以及不允许我找到第一个问题的问题,是程序的答案发生了变化。这是我的终端的副本:
$./list
a
a
p,
$./list
a
a
�,
$./list
a
a
,
$./list
a
a
0,
$./list
a
,
$./list
a
a
�,
所需的输出是:
$./list
a
a
a,
我不知道为什么会这样,我想知道。谢谢!
答案 0 :(得分:1)
q->first = &m;
q->last = &m;
这些存在于具有自动存储持续时间的内存中,一旦声明它的作用域结束就不会存在 - 在范围外访问它就像你所做的那样是未定义的行为。
解决方案是使用*alloc
(malloc
/ calloc
等)动态分配内存,然后您可以传递它们。唯一的事情就是你需要在完成它之后释放它们。这样的事情: - (是的,你可以/应该根据需要修改它)
struct Member* m = malloc(sizeof *m);
if(!m){ perror("malloc");exit(EXIT_FAILURE);}
m->ch = c;
q->first = m;
q->last = m;
...