我试图在C中创建一个链表,而这篇文章是指我试图在结构中的变量中分配用户输入的字符串值的部分。如果我使用strcpy()而不是strdup(),该程序可以完美地编译,但是我会得到不需要的输出。
程序可以正常编译,不给出警告或错误。如果使用strdup(),那么程序将按预期工作,但是我想知道为什么当使用strcpy()时它不起作用。在传递名称字符串时,在打印列表时,它有时会打印为null,然后终止,或者打印“ Name:Name:Name:Name:Nam”或其他此类不可预测的错误。任何其他评论或批评都将不胜感激,同时我也正开始学习该语言,谢谢。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct addressBook {
char *name;
int age;
char *phoneNumber;
struct addressBook *next;
};
static struct addressBook *head = NULL;
static struct addressBook *current;
static struct addressBook *createNew;
//function prototypes
void addNode(void);
struct addressBook * createNode(void);
void printAddressBook(void);
void printStats(void);
int main(void)
{
addNode();
addNode();
printAddressBook();
addNode();
addNode();
printAddressBook();
}
struct addressBook * createNode(void)
{
struct addressBook *newNode;
newNode = (struct addressBook *) malloc(sizeof(struct addressBook));
if (newNode == NULL)
{
puts("Memory error");
exit(1);
}
printf("\nEnter persons name: ");
char name[20];
scanf("%s", name);
strcpy(newNode -> name, name); //produces unpredictable results
//newNode -> name = strdup(name); Works fine with strdup
printf("Enter persons age: ");
scanf("%d", &newNode -> age);
printf("Enter persons phone number: ");
char phoneNumber[15];
scanf("%s", phoneNumber);
strcpy(newNode -> phoneNumber, phoneNumber); //produces unpredictable
results
//newNode -> phoneNumber = strdup(phoneNumber); Works fine with strdup
return(newNode);
}
void addNode(void)
{
createNew = createNode();
current = createNew;
current -> next = head;
head = current;
}
void printAddressBook(void)
{
struct addressBook *temp;
temp = head;
while(temp)
{
printf("Name: %s\nAge: %d\nPhoneNumber: %s\n\n\n",
temp -> name,
temp -> age,
temp -> phoneNumber);
temp = temp -> next;
}
}
答案 0 :(得分:6)
定义char *name;
之类的指针时,它指向某个随机位置,因为您尚未初始化它。写入指针是非法的,这样做会调用未定义行为。
strcpy
基本上将字符串写入此调用UB的随机指针位置。
另一方面,strdup
为字符串动态分配所需的内存,将字符串复制到该位置,然后返回该位置的开始。您可以对该存储位置进行读取/写入,因此这是有效的。