Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 创建排队对象列表时出现分段错误_C_Pointers_Object_Linked List - Fatal编程技术网

C 创建排队对象列表时出现分段错误

C 创建排队对象列表时出现分段错误,c,pointers,object,linked-list,C,Pointers,Object,Linked List,任务是在main中创建对象,并将它们传递给其他函数,这些函数将创建队列类型的列表。这就是我使用的算法: 编写一个Node*类型的函数,它将返回指向列表中最后一个节点的指针 要在列表的末尾插入节点,需要获取指向最后一个节点的指针 创建新的节点 为新创建的节点分配已传递给函数的对象 使上一个节点的指向下一个 代码如下: typedef struct Node{ int val; char str[30]; struct Node *next; }Node; void printList(con

任务是在
main
中创建对象,并将它们传递给其他函数,这些函数将创建队列类型的列表。这就是我使用的算法:

  • 编写一个
    Node*
    类型的函数,它将
    返回
    指向列表中最后一个
    节点的指针

  • 要在列表的末尾插入
    节点
    ,需要获取指向最后一个
    节点的指针

  • 创建新的
    节点
  • 为新创建的
    节点
    分配已传递给函数的对象
  • 使上一个
    节点的
    指向下一个
代码如下:

typedef struct Node{
int val;
char str[30];
struct Node *next;
}Node;

void printList(const Node * head);
void queue(Node *head, Node *object);
Node *getLast(Node *head);

int main(void){

Node *head = NULL;
Node *object = (Node *)malloc(sizeof(Node));
int c = 0;
while(1){
    printf("This int will be stored in Node %d.\n", ++c);
    scanf("%d", &object->val);
    if(!object->val){
        puts("You've decided to stop adding Nodes.");
        break;
    }
    fflush(stdin);
    printf("This string will be stored in Node %d.\n", c);
    fgets(object->str, 30, stdin);
    if(!(strcmp(object->str, "\n\0"))){
        puts("You've decided to stop adding Nodes.");
        break;
    }


queue(head, object);


}
printList(head);

return 0;
}

void printList(const Node *head){
if(head == NULL){
    puts("No list exists.");
    exit(1);
}
while(1){

    printf("|||Int: %d|||String: %s|||\n", head->val, head->str);

    if(head->next){
        head = head->next;
    }
    else{
        break;
    }
}
}

Node *getLast(Node *head){
if(head == NULL){
    return NULL;
}
while(head->next){
    head = head ->next;
}
return head;
}

void queue(Node *head, Node *object){
Node *last = getLast(head);
Node *tmp = (Node *)malloc(sizeof(Node));
*tmp = *object;
tmp -> next = NULL;
last -> next = tmp;
}

问题可能在于让
getLast
返回
NULL
。但同样,当我创建一个仅由
int
组成的列表时,这种情况也起到了作用,正如注释部分所指出的,
last->next=tmp
第一次调用queue()失败,因为getLast()返回NULL。正确的解决方案如下:

  void queue(Node **head, Node *object){                                          
  Node *last = getLast(*head);                                                  
  Node *tmp = (Node *)malloc(sizeof(Node));                                     
  *tmp = *object;                                                               
  tmp -> next = NULL;                                                           

  if (last != NULL)                                                             
    last -> next = tmp;                                                         
  else                                                                          
    *head = tmp;                                                                
}

并从main()调用
queue(&head,object)

我怀疑它在没有字符串的情况下是否有效。对于调用的第一个元素
getlast
,它返回
NULL
。然后访问内存
last->next=tmp
;这是UB,可能会崩溃。节点中的值是整数还是整数和字符串并不重要。您只分配一个节点。(循环外)调试器说什么?您确实通过调试器运行了它,对吗?@Devlus这是在线C编译器所说的:
“程序在qn.C:223 last->next=tmp中接收到信号0x000000000040E81;”
Visual Studio:
“引发异常:读取访问冲突。**head**是0xcdcdcd”
关于
if(head->next){
getLast
函数中。可能是这样,但在您到这里寻求帮助之前,您确实尝试过调试代码以找出问题所在。