C编程使用链表时出现段错误和错误输出
C programming segmentation fault error and wrong outputs when using linked list
我一直在尝试在 C 中使用简单的链表,但是我得到了错误的输出,然后是分段错误。
这个程序的目的是从一个文本文件中获取 3 个参数,并将它们作为一个对象放在链表中。每次读取新行时,都会使用 newData
方法将其放入列表中,并最终使用 display
方法将其显示到控制台。
然而,当我尝试这样做时,我只输出添加到链表的最后一项,并且
它显示了我的文本文件中存在的行数,然后是分段错误,我无法理解为什么。
如果有人知道这个问题或如何解决它,我们将不胜感激。代码如下所示。
main.c:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "param.h"
#include "function.h"
#include "lists.h"
int main(int argc, char *argv[])
{
char *p1;
int p2;
int p3;
FILE *in;
char *temp;
char param[100];
in = fopen(argv[1],"r");
while (fgets(param,100,in) != NULL) {
temp = strdup(param);
p1 = strsep(&temp,",");
p2 = atoi(strsep(&temp,","));
p3 = atoi(strsep(&temp,","));
newData(p1,p2,p3);
free(temp);
}
fclose(in);
display();
return 0;
}
lists.c:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "param.h"
#include "function.h"
#include "lists.h"
static struct node*head;
static struct parameters tempTaskObject;
static int status = 1;
void newData(char * p1, int p2, int p3){
if (status == 1)
{
head = (struct node*)malloc(sizeof(struct node));
}
tempTaskObject.p1 = p1;
tempTaskObject.p2 = p2;
tempTaskObject.p3 = p3;
insert(&head,&tempTaskObject);
status = 0;
}
void display(){
traverse(head);
}
function.c:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "function.h"
#include "param.h"
void insert(struct node **head, Parameters *newParameters) {
struct node *newNode = malloc(sizeof(struct node));
newNode->parameters = newParameters;
newNode->next = *head;
*head = newNode;
}
void traverse(struct node *head) {
struct node *temp;
temp = head;
while (temp != NULL) {
printf("[%s] [%d] [%d]\n",temp->parameters->p1, temp->parameters->p2, temp->parameters->p3);
temp = temp->next;
}
}
param.h:
#ifndef TASK_H
#define TASK_H
typedef struct parameters {
char *p1;
int p2;
int p3;
} Parameters;
#endif
lists.h:
#define MIN_PRIORITY 1
#define MAX_PRIORITY 10
void newData(char *p1, int p2, int p3);
void display();
function.h:
#include "param.h"
struct node {
Parameters * parameters;
struct node *next;
};
void insert(struct node **head, Parameters * parameters);
void traverse(struct node *head);
[测试输入 1]:
P1, 1, 11
P2, 2, 22
P3, 3, 33
P4, 4, 44
P5, 5, 55
P6, 6, 66
P7, 7, 77
P8, 8, 88
[测试输出 1]:
P8, 8, 88
P8, 8, 88
P8, 8, 88
P8, 8, 88
P8, 8, 88
P8, 8, 88
P8, 8, 88
P8, 8, 88
Segmentation fault (core dumped)
[测试输入 2]:
P1, 1, 11
P2, 2, 22
P3, 3, 33
[测试输出 2]:
P3, 3, 33
P3, 3, 33
P3, 3, 33
Segmentation fault (core dumped)
对于这个 while 循环中的初学者
while (fgets(param,100,in) != NULL) {
temp = strdup(param);
p1 = strsep(&temp,",");
p2 = atoi(strsep(&temp,","));
p3 = atoi(strsep(&temp,","));
newData(p1,p2,p3);
free(temp);
}
免费的呼唤
free(temp);
没有效果,因为 temp 将等于 NULL。
另一方面,函数 newData
也可以调用未定义的行为,因为它在第一次调用时使用 struct node
类型的未初始化对象,将其传递给函数 insert。
if (status == 1)
{
head = (struct node*)malloc(sizeof(struct node));
}
而且你总是在这个初始化语句中使用指向同一个全局对象的指针static struct parameters tempTaskObject;
newNode->parameters = newParameters;
请注意,当函数依赖于大量全局变量时,以这种方式定义函数是个坏主意。
我一直在尝试在 C 中使用简单的链表,但是我得到了错误的输出,然后是分段错误。
这个程序的目的是从一个文本文件中获取 3 个参数,并将它们作为一个对象放在链表中。每次读取新行时,都会使用 newData
方法将其放入列表中,并最终使用 display
方法将其显示到控制台。
然而,当我尝试这样做时,我只输出添加到链表的最后一项,并且 它显示了我的文本文件中存在的行数,然后是分段错误,我无法理解为什么。
如果有人知道这个问题或如何解决它,我们将不胜感激。代码如下所示。
main.c:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "param.h"
#include "function.h"
#include "lists.h"
int main(int argc, char *argv[])
{
char *p1;
int p2;
int p3;
FILE *in;
char *temp;
char param[100];
in = fopen(argv[1],"r");
while (fgets(param,100,in) != NULL) {
temp = strdup(param);
p1 = strsep(&temp,",");
p2 = atoi(strsep(&temp,","));
p3 = atoi(strsep(&temp,","));
newData(p1,p2,p3);
free(temp);
}
fclose(in);
display();
return 0;
}
lists.c:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "param.h"
#include "function.h"
#include "lists.h"
static struct node*head;
static struct parameters tempTaskObject;
static int status = 1;
void newData(char * p1, int p2, int p3){
if (status == 1)
{
head = (struct node*)malloc(sizeof(struct node));
}
tempTaskObject.p1 = p1;
tempTaskObject.p2 = p2;
tempTaskObject.p3 = p3;
insert(&head,&tempTaskObject);
status = 0;
}
void display(){
traverse(head);
}
function.c:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "function.h"
#include "param.h"
void insert(struct node **head, Parameters *newParameters) {
struct node *newNode = malloc(sizeof(struct node));
newNode->parameters = newParameters;
newNode->next = *head;
*head = newNode;
}
void traverse(struct node *head) {
struct node *temp;
temp = head;
while (temp != NULL) {
printf("[%s] [%d] [%d]\n",temp->parameters->p1, temp->parameters->p2, temp->parameters->p3);
temp = temp->next;
}
}
param.h:
#ifndef TASK_H
#define TASK_H
typedef struct parameters {
char *p1;
int p2;
int p3;
} Parameters;
#endif
lists.h:
#define MIN_PRIORITY 1
#define MAX_PRIORITY 10
void newData(char *p1, int p2, int p3);
void display();
function.h:
#include "param.h"
struct node {
Parameters * parameters;
struct node *next;
};
void insert(struct node **head, Parameters * parameters);
void traverse(struct node *head);
[测试输入 1]:
P1, 1, 11
P2, 2, 22
P3, 3, 33
P4, 4, 44
P5, 5, 55
P6, 6, 66
P7, 7, 77
P8, 8, 88
[测试输出 1]:
P8, 8, 88
P8, 8, 88
P8, 8, 88
P8, 8, 88
P8, 8, 88
P8, 8, 88
P8, 8, 88
P8, 8, 88
Segmentation fault (core dumped)
[测试输入 2]:
P1, 1, 11
P2, 2, 22
P3, 3, 33
[测试输出 2]:
P3, 3, 33
P3, 3, 33
P3, 3, 33
Segmentation fault (core dumped)
对于这个 while 循环中的初学者
while (fgets(param,100,in) != NULL) {
temp = strdup(param);
p1 = strsep(&temp,",");
p2 = atoi(strsep(&temp,","));
p3 = atoi(strsep(&temp,","));
newData(p1,p2,p3);
free(temp);
}
免费的呼唤
free(temp);
没有效果,因为 temp 将等于 NULL。
另一方面,函数 newData
也可以调用未定义的行为,因为它在第一次调用时使用 struct node
类型的未初始化对象,将其传递给函数 insert。
if (status == 1)
{
head = (struct node*)malloc(sizeof(struct node));
}
而且你总是在这个初始化语句中使用指向同一个全局对象的指针static struct parameters tempTaskObject;
newNode->parameters = newParameters;
请注意,当函数依赖于大量全局变量时,以这种方式定义函数是个坏主意。