我正在用一堆 ListNodes 实现一个 LinkedList,这些 ListNodes 是包含一些关于人的基本信息的结构。我有两个文件,一个是 main.c,另一个是 main.h。每当我尝试通过将根传递给函数来打印列表时,我都会收到错误消息。
这是main.c:
#include "main.h"
/* Edward Nusinovich
This C file is going to have a LinkedList containing information about people.
The user can interact with it and manipulate the list.
*/
int main(int argc, char **argv){
if(!checkIfValidArguments(argc).value){return -1;}
ListNode *root = askForDetails(1,argv);
ListNode *current = root;
current->next = NULL;
ListNode *temp;
int index = 2;
while(index<argc){
temp = askForDetails(index,argv);
current->next = temp;
current = current->next;
index++;
}
userLoop(root);
return 0;
}
在我的 main.h 文件中,我在函数“userLoop”中打印 root 参数的属性没有问题,但是一旦我将 ListNode *root 传递给“print”或“stuff”,我就会遇到段错误尝试打印其值。
这是 main.h:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define true 1
#define false 0
typedef struct bool{
int value:1;
} boolean;
//this is going to store info about a person
typedef struct people{
char *name;
char *hairColor;
char *eyeColor;
char *age;
struct people *next;
} ListNode;
//using a 1 bit bitfield we have constructed, stores whether or not the user has entered a proper number of inputs
boolean checkIfValidArguments(int numArgs){
boolean validArguments;
if(numArgs>1){validArguments.value=true;}
else{validArguments.value=false; printf("We need some names of people.\n");}
return validArguments;
}
//this will construct a new Person and return him to
ListNode *askForDetails(int personIndex, char **argv){
ListNode toReturn;
char *name = argv[personIndex];
printf("Please enter the hair color, eye color, and age of %s.\n",name);
char *inBuf=malloc(100);
char nextchar=getchar();
int index = 0;
if(nextchar!='\n'){inBuf[index]=nextchar; index++;}
while((nextchar=getchar())!='\n'){
inBuf[index] = nextchar;
index ++;
}
toReturn.name = name;
toReturn.hairColor = strtok(inBuf," ");
toReturn.eyeColor = strtok(NULL," ");
toReturn.age = strtok(NULL,"\n");
ListNode *newNode = malloc(sizeof(ListNode));
newNode = &toReturn;
return newNode;
}
char *getInput(char *message){
printf("%s",message);
char *inBuf = malloc(40);
char nextchar=getchar();
int index = 0;
if(nextchar!='\n'){inBuf[index]=nextchar; index++;}
while((nextchar=getchar())!='\n'){
inBuf[index] = nextchar;
index ++;
}
return inBuf;
}
void addToEnd(ListNode *root){
ListNode *current = root;
char *inBuf = getInput("\nEnter the name of a person who you want to add: \n");
ListNode *toAdd = malloc(sizeof(ListNode));
toAdd = askForDetails(0,&inBuf);
toAdd->name = inBuf;
toAdd->next = NULL;
while((current->next) != NULL){
current = current->next;
}
current->next = toAdd;
}
void print(ListNode *root){
printf("The name is %s.\n",root->name);
/*
ListNode *current = root;
do{
printf("\n%s's hair is %s, their eyes are %s and they are %s years old.\n",current->name,current->hairColor,current->eyeColor,current->age);
current = current->next;
}while(current!=NULL);
*/
}
void remEnd(ListNode *root){
ListNode *current = root;
if(current == NULL){ return; }
}
void addAfter(ListNode *root){
ListNode *current = root;
char *name = getInput("\nWho do you want to add after?\n");
int comparison = 0;
while(current!=NULL&&(comparison = strcmp(name,current->name))!=0){
current = current -> next;
}
if(current==NULL){printf("\nIndividual not found.\n"); return;}
else{
char *newPerson = getInput("What's the name of the person you wish to add? ");
ListNode *toAdd = askForDetails(0,&newPerson);
ListNode *next = current->next;
current -> next = toAdd;
toAdd->next = next;
return;
}
}
void stuff(ListNode *root){
printf("name is %s.\n",root->name);
printf("Root lives at %u.\n",root);
}
void userLoop(ListNode *root){
char input = ' ';
printf("Root lives at %u.\n",root);
while(true){
printf("name is %s.\n",root->name);
if(input!='\n'){
printf("\nWhat would you like to do with your list:\n");
printf("A) Add an element at the end of the list\n");
printf("B) Remove an element from the end of the list\n");
printf("C) Add an element after an element on your list\n");
printf("D) Print your list\n");
printf("E) Quit this program\n\n");
}
input = getchar();
switch(input){
case 'A': addToEnd(root); break;
case 'B': remEnd(root); break;
case 'C': addAfter(root); break;
case 'D': stuff(root); break;
case 'E': return;
}
}
}
当在两个函数中打印 root 内存中的地址时,我得到了相同的值,所以我不确定为什么我无法在一个函数而不是另一个函数中访问 root 中的值。
非常感谢您的帮助。
最佳答案
您似乎不太了解内存模型在 C 中的工作原理。您的违规代码可能是:
ListNode *newNode = malloc(sizeof(ListNode));
newNode = &toReturn;
return newNode;
这会返回一个指向局部变量 toReturn
的指针,而不是 malloc 的内存地址。您需要将数据从 toReturn
复制到您的 malloc 内存空间中。但是,更糟糕的是,您没有为每个字符串分配空间,因此每个节点都指向相同的输入缓冲区。这应该可行,因为您为每个节点分配了 malloc,但是如果
你要开始删除节点管理你的内存会有点尴尬。您也不确定缓冲区中是否有足够的空间。
我建议查看一些在线资源(或者最好是一本书)以复习 C 内存的工作原理。
编辑:我没有在线学习 C,但快速谷歌搜索出现了 this , 乍一看似乎是一个不错的资源。
我建议查看 book list .我使用了 C Programming A Modern Approach。
关于c - 在一个函数而不是另一个函数中访问同一内存时发生段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36439806/