C 变量覆盖值

标签 c pointers

您好,我实现了一个链接列表,但在更新我创建的 struc 进程的变量时遇到了麻烦。这是示例代码:

typedef struct Process {
    int pid;
    char name[256];
    int prior;    
    int state;
    int start_time;   
} Process;

typedef struct Node {
    Process *value;
    struct Node *next;
} Node;


Node *create_node(){
    Node *temp = malloc(sizeof(Node));
    temp->value = NULL;
    temp->next = NULL;
    return temp;
}

void append(Node *head, Node *nodo){
    Node *current = head;
    while (current->next != NULL){
        current = current->next;
    }    
    current->next = nodo;
}



void add_attr(char *string, Process *procc){    
    char *pch;
    pch = strtok(string, " ");
    for (int i = 0; i < 3; i++){
        if (i == 0){
            strcpy(procc->name,pch);              
        }
        else if(i == 1){           
            int aux = atoi(pch);            
            procc->prior = aux;                                 
        }
        else{            
            int aux1 = atoi(pch);
            procc->start_time = aux1;                
        }
        pch = strtok(NULL, " ");
    }


int main(int argc, char * argv []) {    
    FILE *fp;
    int pid = 0;
    char *line = NULL;
    size_t len = 0;
    ssize_t read;
    fp = fopen(argv[1],"r");
    Node *process_list = create_node();    
    Process *proc = malloc(sizeof(Process));
    proc->pid = pid;
    proc->state = 0;
    process_list->value = proc;
    pid += 1 ;
    while ((read = getline(&line, &len, fp)) != -1) {
        printf("%s\n",line);        
        add_attr(line, proc);
        printf("---------------------------------------------------------\n");
        printf("pointer proc memory dir = %p\n", proc);
        printf("pid = %d\n",proc->pid);
        printf("name = %s\n",proc->name);
        printf("pior = %d\n",proc->prior);
        printf("state = %d\n",proc->state);
        printf("start_time = %d\n",proc->start_time);
        printf("----------------------------------------------------------\n");
        Node *nodo = create_node();
        Process *proc = malloc(sizeof(Process));
        proc->pid = pid;       
        proc->state = 0;
        nodo->value = proc;
        append(process_list, nodo); 
        pid = pid +1;
    }    
    fclose(fp);
    return 0;
}

有main() 正如你所看到的,我打印了结构中变量的状态来查看它们的值,除了 pid 没有改变之外,一切都很顺利。 while 循环完成后,我打印了链接列表中的所有进程及其属性,它们都发生了变化。在这里您可以看到带有输出的 SS。 enter image description here

我真的不知道我的程序发生了什么,任何帮助都会很棒,我知道这是一个非常具体的案例,但我不知道如何制作一个显示相同问题的工作示例。 (*我现在更新了 pid 的输出,但主要问题没有解决,我仍然不明白为什么 Process attr 会改变)。

Input sample:
p1 2 3 10 1 2 3 4 5 6 7 8 8 9
p2 1 4 8 6 2 6 4 3 2 2 1
p3 3 5 5 1 2 6 7 8

最佳答案

AFAIK,pid = pid++; 是未定义的行为。

改用pid = pid + 1pid++pid += 1

<小时/>

更新:

您在打印后设置 proc->pid ,因此它会打印为零。实际上,它打印的就是 malloc 返回的内容,所以它可以是任何东西,只是大多数时候碰巧为零。

但是,您还有另一个问题。您在循环底部附加一个新节点,以期在下一个循环迭代中读取该节点的内容。

因此,由于您附加了“前一个”,因此生成的链表将具有过多的节点,并且最后一个节点将包含垃圾数据。您在循环本身中看不到这一点,但在后续列表遍历[和打印]期间看到这一点。

我已经创建了您的程序的两个版本。一张带有注释的错误。还有一个清理版本。

这是带注释的版本[打印正确]:

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

typedef struct Process {
    int pid;
    char name[256];
    int prior;
    int state;
    int start_time;
} Process;

typedef struct Node {
    Process *value;
    struct Node *next;
} Node;

Node *
create_node()
{
    Node *temp = malloc(sizeof(Node));

    temp->value = NULL;
    temp->next = NULL;
    return temp;
}

void
append(Node * head, Node * nodo)
{
    Node *current = head;

    while (current->next != NULL) {
        current = current->next;
    }
    current->next = nodo;
}

void
add_attr(char *string, Process * procc)
{
    char *pch;

    pch = strtok(string, " ");
    for (int i = 0; i < 3; i++) {
        if (i == 0) {
            strcpy(procc->name, pch);
        }
        else if (i == 1) {
            int aux = atoi(pch);

            procc->prior = aux;
        }
        else {
            int aux1 = atoi(pch);

            procc->start_time = aux1;
        }
        pch = strtok(NULL, " ");
    }
}

int
main(int argc, char *argv[])
{
    FILE *fp;
    int pid = 0;
    char *line = NULL;
    size_t len = 0;
    ssize_t read;

    fp = fopen(argv[1], "r");
    Node *process_list = create_node();
    Process *proc = malloc(sizeof(Process));

    proc->pid = pid;
    proc->state = 0;
    process_list->value = proc;
    pid += 1;
    while ((read = getline(&line, &len, fp)) != -1) {
        printf("%s\n", line);
        add_attr(line, proc);

// NOTE/FIX: this is the correct place to set the pid -- _before_ printing
#if 0
        proc->pid = pid;
#endif

        printf("---------------------------------------------------------\n");
        printf("pointer proc memory dir = %p\n", proc);
        printf("pid = %d\n", proc->pid);
        printf("name = %s\n", proc->name);
        printf("pior = %d\n", proc->prior);
        printf("state = %d\n", proc->state);
        printf("start_time = %d\n", proc->start_time);
        printf("----------------------------------------------------------\n");

// NOTE/BUG: this is setting up the _next_ node before it is known if it will
// be filled
        Node *nodo = create_node();
        Process *proc = malloc(sizeof(Process));

// NOTE/BUG: this is set _after_ the printing is done
#if 1
        proc->pid = pid;
#endif

// NOTE/BUG: this is appending the node before it is filled in (i.e. the last
// node in the list will have garbage)
        proc->state = 0;
        nodo->value = proc;
        append(process_list, nodo);

        pid = pid + 1;
    }

    fclose(fp);
    return 0;
}
<小时/>

这是清理后的工作版本:

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

typedef struct Process {
    int pid;
    char name[256];
    int prior;
    int state;
    int start_time;
} Process;

typedef struct Node {
    Process *value;
    struct Node *next;
} Node;

Node *
create_node()
{
    Node *temp = malloc(sizeof(Node));

    temp->value = NULL;
    temp->next = NULL;
    return temp;
}

void
append(Node * head, Node * nodo)
{
    Node *current = head;

    while (current->next != NULL) {
        current = current->next;
    }
    current->next = nodo;
}

void
add_attr(char *string, Process * procc)
{
    char *pch;

    pch = strtok(string, " ");
    for (int i = 0; i < 3; i++) {
        if (i == 0) {
            strcpy(procc->name, pch);
        }
        else if (i == 1) {
            int aux = atoi(pch);

            procc->prior = aux;
        }
        else {
            int aux1 = atoi(pch);

            procc->start_time = aux1;
        }
        pch = strtok(NULL, " ");
    }
}

int
main(int argc, char *argv[])
{
    FILE *fp;
    int pid = 0;
    char *line = NULL;
    size_t len = 0;
    ssize_t read;

    fp = fopen(argv[1], "r");
    Node *process_list = create_node();
    Process *proc = malloc(sizeof(Process));

    proc->pid = pid;
    proc->state = 0;
    process_list->value = proc;

    while ((read = getline(&line, &len, fp)) != -1) {
        printf("%s\n", line);

        Process *proc = malloc(sizeof(Process));
        add_attr(line, proc);
        proc->state = 0;

        pid += 1;
        proc->pid = pid;

        Node *nodo = create_node();
        nodo->value = proc;
        append(process_list, nodo);

        printf("---------------------------------------------------------\n");
        printf("pointer proc memory dir = %p\n", proc);
        printf("pid = %d\n", proc->pid);
        printf("name = %s\n", proc->name);
        printf("pior = %d\n", proc->prior);
        printf("state = %d\n", proc->state);
        printf("start_time = %d\n", proc->start_time);
        printf("----------------------------------------------------------\n");
    }

    fclose(fp);

    return 0;
}

关于C 变量覆盖值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43106245/

相关文章:

C++在 vector 迭代中删除并返回指向对象的指针

c++ - 在 C++ 中的函数内更改二维数组的值

c - va_arg 总是运行 4 次

c - C语言二维数组

c - 如何使用 GCC 在每个函数的开头/结尾处植入我自己的代码

c - 如何在 C 中使用二维指针数组来存储字符串?

c - 在指向指针链的指针末尾初始化值

C语言: is it bad to define functions in ..h文件中没有声明的c文件?

c - 数组的POD结构

在 Rust 中将 C 指针转换为结构