You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言报错:invalid type argument of '->'(have 'Queue') 解决问询

问题分析与解决方案

首先,咱们来拆解你遇到的几个核心问题:

1. 编译错误的直接原因:结构体访问符号混用+类型不匹配

你在代码里写了:

p.pointer_instrucoes.head=atoi(s2);
// 还有后面的
printf("%d\n",p->pointer_instrucoes->head);
  • 首先,PCB结构体里的pointer_instrucoes是**Queue类型的实例**(不是指针),所以访问它的成员应该用.而不是->,这就是编译报错「invalid type argument of '->'」的直接原因。
  • 其次,Queue的head是Node*类型(指向节点的指针),你直接给它赋值atoi(s2)得到的int值,这是严重的类型不匹配,就算编译过也会导致内存错误。

2. 设计层面的核心问题:队列的存储类型不符合需求

你想把指令数字存在PCB的队列里,但当前的Node结构体定义是存储PCB*指针,这完全和你的需求相悖——队列应该存储int类型的指令,而不是PCB对象。

3. PCB初始化错误

在new_pcb函数里,你写了p->pointer_instrucoes=0;,这是把整个Queue结构体赋值为0,属于非法操作,正确的做法是初始化一个空队列。


修正后的完整代码

第一步:修正queue2.h的结构体定义

调整Node和PCB的定义,让队列存储指令数字,同时把PCB里的队列改成指针类型:

#include <stdbool.h>

// 先定义基础结构体
typedef struct Node Node;
typedef struct Queue Queue;
typedef struct PCB PCB;

// Node存储int类型的指令
typedef struct Node {
    int instruction;
    Node *next;
} Node;

// Queue结构不变,但后续会添加入队函数
typedef struct Queue {
    int sizeQueue;
    int limit;
    Node *head;
} Queue;

// PCB里的队列改为指针类型
typedef struct PCB {
    int id;
    int program_counter;
    int size;
    Queue *pointer_instrucoes;
    int instante;
} PCB;

// 函数声明调整
PCB * new_pcb(int id);
Node * new_node(int instr);
Queue * new_queue(int limit);
// 添加入队函数
bool enqueue(Queue *q, int instr);

第二步:修正queue2.c的实现

更新节点、队列、PCB的创建函数,添加入队逻辑:

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

Node * new_node(int instr) {
    Node *n = malloc(sizeof(Node));
    if (!n) return NULL; // 检查内存分配
    n->instruction = instr;
    n->next = NULL;
    return n;
}

Queue * new_queue(int limit) {
    Queue *q = malloc(sizeof(Queue));
    if (!q) return NULL;
    q->limit = limit;
    q->head = NULL;
    q->sizeQueue = 0;
    return q;
}

PCB * new_pcb(int id) {
    PCB *p = malloc(sizeof(PCB));
    if (!p) return NULL;
    p->id = id;
    // 初始化一个上限为100的队列(可根据需求调整)
    p->pointer_instrucoes = new_queue(100);
    p->program_counter = 0;
    p->size = 0;
    p->instante = 0; // 初始化默认值
    return p;
}

// 实现入队函数:把指令添加到队列尾部
bool enqueue(Queue *q, int instr) {
    if (!q || q->sizeQueue >= q->limit) {
        return false; // 队列满或无效
    }
    Node *newNode = new_node(instr);
    if (!newNode) return false;
    
    if (q->head == NULL) {
        q->head = newNode;
    } else {
        Node *temp = q->head;
        while (temp->next != NULL) {
            temp = temp->next;
        }
        temp->next = newNode;
    }
    q->sizeQueue++;
    return true;
}

第三步:修正main.c的逻辑

修复结构体访问错误,正确解析每行的指令并加入队列:

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

int le_ficheiro(char* filename) {
    FILE *ficheiro = fopen(filename, "r");
    if (!ficheiro) {
        perror("Failed to open file");
        exit(EXIT_FAILURE);
    }

    size_t len = 0;
    char *line = NULL;
    int contador = 1;

    while ((getline(&line, &len, ficheiro)) != -1) {
        // 创建新PCB
        PCB *p = new_pcb(contador);
        if (!p) {
            perror("Failed to create PCB");
            exit(EXIT_FAILURE);
        }

        // 分割实例和指令部分
        char *sp = strchr(line, ' ');
        if (!sp) {
            fprintf(stderr, "Invalid line format\n");
            free(p);
            continue;
        }

        // 解析实例
        char *s1 = strndup(line, sp - line);
        p->instante = atoi(s1);
        free(s1); // 用完释放内存

        // 解析指令部分:分割每个数字
        char *token = strtok(sp + 1, " \n");
        while (token != NULL) {
            int instr = atoi(token);
            // 把指令加入PCB的队列
            if (!enqueue(p->pointer_instrucoes, instr)) {
                fprintf(stderr, "Failed to enqueue instruction %d for PCB %d\n", instr, p->id);
            }
            token = strtok(NULL, " \n");
        }

        // 打印测试信息
        printf("PCB ID: %d\n", p->id);
        printf("Instante: %d\n", p->instante);
        printf("Number of instructions: %d\n", p->pointer_instrucoes->sizeQueue);
        // 遍历队列打印指令
        Node *temp = p->pointer_instrucoes->head;
        printf("Instructions: ");
        while (temp != NULL) {
            printf("%d ", temp->instruction);
            temp = temp->next;
        }
        printf("\n-------------------------\n");

        contador++;
        // 这里可以根据需求保存PCB到链表或数组,避免内存泄漏
        // 示例中暂时不处理,实际项目需要管理这些内存
    }

    fclose(ficheiro);
    if (line) free(line);
    return EXIT_SUCCESS;
}

int main() {
    char name[50];
    printf("Name of the file: ");
    scanf("%s", name);
    return le_ficheiro(name);
}

测试输入验证

用你提供的输入示例:

1 01 02 03 04 05
2 01 02 03 02 11

运行程序后会输出:

Name of the file: test.txt
PCB ID: 1
Instante: 1
Number of instructions: 5
Instructions: 1 2 3 4 5 
-------------------------
PCB ID: 2
Instante: 2
Number of instructions: 5
Instructions: 1 2 3 2 11 
-------------------------

额外注意事项

  • 内存管理:示例中创建的PCB和队列需要在程序结束前释放,避免内存泄漏,你可以添加一个free_pcb函数来递归释放PCB和其队列的所有节点。
  • 队列上限:new_queue的limit参数可以根据你的实际需求调整,或者改成动态扩容的队列。

内容的提问来源于stack exchange,提问作者user7391306

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 06:46:47