[英]In C I am getting segmentation fault, i do not know why
我正在创建一个在一个实例中存储多个事物的二进制搜索树,但遇到了两个错误。 函数insert
中发生的第一个操作比随机停止时起作用,第二个出现在print_tree_inorder
,我不知道为什么会破坏它。
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <stdbool.h>
#include <string.h>
#include <malloc.h>
char* nameArray[50] = {};
char* number[50] = {};
char* ID[50] = {};
char* hours[50] = {};
char* pPH[50] = {};
int flag;
typedef struct node
{
char* name;
char* phoneNum;
char* ID;
char* hours;
char* pPH;
struct node * left;
struct node * right;
} node_t;
void insert(node_t * tree, char* name, char* phoneNum, char* hours, char* pPH);
void print_tree_inorder(node_t * current);
int main()
{
char* n,p,id,h,pph;
int numberOfTimes = 0;
node_t * test_list = malloc(sizeof(node_t));
/* set values explicitly, alternative would be calloc() */
test_list->name = "";
test_list->phoneNum = "";
//test_list->ID = "";
test_list->hours = "";
test_list->pPH = "";
test_list->left = NULL;
test_list->right = NULL;
printf("Please enter in the amount of people you want: ");
scanf("%d",&numberOfTimes);
printf("\n");
for(int i = 0; i<numberOfTimes; i++){
printf("Please enter in name: ");
scanf("%s", &n);
nameArray[i] = n;
printf("Please enter in PhoneNumber: ");
scanf("%s", &p);
number[i] = p;
printf("Please enter in Hours: ");
scanf("%s", &h);
hours[i] = h;
//printf("\n");
printf("Please enter in pay per hour: ");
scanf("%s", &pph);
pPH[i] = pph;
insert(test_list,nameArray[i],number[i],hours[i], pPH[i] );
}
printf("\n In order\n");
print_tree_inorder(test_list);
}
void insert(node_t * tree, char* name, char* phoneNum, char* hours, char* pPH)
{
//unsigned int number = (unsigned int)ptr
if (tree->name == 0)
{
/* insert on current (empty) position */
tree->name = name;
tree->phoneNum = phoneNum;
//tree->ID = ID;
tree->hours = hours;
tree->pPH = pPH;
}
else
{
if ( strcmp(tree->name, name) > 0)
{
/* insert left */
if (tree->left != NULL)
{
insert(tree->left, name, phoneNum, hours, pPH);
}
else /* no left nodes*/
{
tree->left = malloc(sizeof(node_t));
/* set values explicitly, alternative would be calloc() */
tree->left->name = name;
tree->left->phoneNum = phoneNum;
tree->left->hours = hours;
tree->left->pPH = pPH;
tree->left->left = NULL;
tree->left->right = NULL;
}
}
else /*add node to right */
{
if ( strcmp(tree->name, name) <= 0)
{
/* insert right */
if (tree->right != NULL)
{
insert(tree->right, name, phoneNum, hours, pPH);
}
else
{
tree->right = malloc(sizeof(node_t));
/* set values explicitly, alternative would be calloc() */
tree->right->name = name;
tree->right->phoneNum = phoneNum;
tree->right->hours = hours;
tree->right->pPH = pPH;
tree->right->left = NULL;
tree->right->right = NULL;
}
}
}
}
}
void print_tree_inorder(node_t * current) {
if (current == NULL) return;
print_tree_inorder(current->left);
printf(" %s %s %s %s\n", current->name, current->phoneNum,current->hours, current->pPH);
print_tree_inorder(current->right);
}
您的代码中的几个问题。 首先, 您不应该包含malloc.h
。 不推荐使用。
看起来在n,p,id,h,pph
变量的声明周围有些混乱。 这个说法:
char* n,p,id,h,pph;
仅声明char *
类型为n
,其余变量p,id,h,pph
声明为char
类型。
让我们来谈谈编译器报告的警告(我正在使用gcc
编译器,并在编译过程中提供了-Wall
和-Wextra
选项):
$ gcc -Wall -Wextra prg.c
prg.c:56:26: warning: format specifies type 'char *' but the argument has type 'char **' [-Wformat]
scanf("%s", &n);
~~ ^~
prg.c:61:24: warning: incompatible integer to pointer conversion assigning to 'char *' from 'char'; take the address with & [-Wint-conversion]
number[i] = p;
^ ~
&
prg.c:64:23: warning: incompatible integer to pointer conversion assigning to 'char *' from 'char'; take the address with & [-Wint-conversion]
hours[i] = h;
^ ~
&
prg.c:68:21: warning: incompatible integer to pointer conversion assigning to 'char *' from 'char'; take the address with & [-Wint-conversion]
pPH[i] = pph;
^ ~~~
&
prg.c:35:15: warning: unused variable 'id' [-Wunused-variable]
char* n,p,id,h,pph;
^
5 warnings generated.
您不应忽略编译器警告消息。 他们出于某种原因在那里。
警告 1
:
n
是char *
类型,因此&n
是char **
类型。 scanf()
的%s
格式说明符期望参数为数组,并且该数组必须至少可input_size+1
字符。
您应该将n
声明为字符数组,如下所示:
char n[50];
// and for input
scanf("%49s", n);
警告 2
:
p
是char
类型,而number[i]
是char *
类型。 因此,分配是不兼容的。 另外, &p
的类型为char *
,这就是为什么编译器未在语句中报告任何警告的原因:
scanf("%s", &p);
但这是不正确的,因为p
是char
类型,并且它没有足够的空间来输入字符串。 阅读更多有关scanf()
格式说明符。
你可以做:
char p[50];
// and for input
scanf("%49s", p);
number[i] = strdup(p);
如果不使用strdup
,则number
数组的所有指针最终都指向同一位置。 另外,您可以将p
声明为char *
并显式处理内存分配/取消分配操作。 完成后,请确保free
strdup
返回的内存。 警告 3
和4
解释相同。
警告 5
:
从代码中删除未使用的变量。
您的代码有很大的改进范围。 尝试自己找出它们。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.