为什么我的C程序在没有任何输入或代码更改的情况下更改每次执行的输出?

时间:2018-02-03 19:07:39

标签: c struct queue

我正在研究我在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,

我不知道为什么会这样,我想知道。谢谢!

1 个答案:

答案 0 :(得分:1)

   q->first = &m;
   q->last = &m;

这些存在于具有自动存储持续时间的内存中,一旦声明它的作用域结束就不会存在 - 在范围外访问它就像你所做的那样是未定义的行为。

解决方案是使用*allocmalloc / calloc等)动态分配内存,然后您可以传递它们。唯一的事情就是你需要在完成它之后释放它们。这样的事情: - (是的,你可以/应该根据需要修改它)

struct Member* m = malloc(sizeof *m);
if(!m){ perror("malloc");exit(EXIT_FAILURE);}
m->ch = c;
q->first = m;
q->last = m;
...