简体   繁体   English

在此程序的情况下,为什么strcpy()函数会产生不需要的输出?

[英]Why does the strcpy() function produce unwanted outputs in the case of this program?

I am trying to create a linked list in C and this post refers to the part where I try to assign a variable in a structure a string value that the user inputs. 我试图在C中创建一个链表,而这篇文章是指我试图在结构中的变量中分配用户输入的字符串值的部分。 The program compiles perfectly yet if I use strcpy() instead of strdup() then I get unwanted output. 如果我使用strcpy()而不是strdup(),则程序可以完美地编译,但是我得到了不需要的输出。

The program compiles fine and gives no warnings or errors. 该程序可以正常编译,并且不给出警告或错误。 If strdup() is used then the program works as intended but I'd like to know why it doesn't work when strcpy() is used instead. 如果使用strdup(),那么程序将按预期工作,但是我想知道为什么当使用strcpy()时它不起作用。 When passing in strings for the names, when the list is printed it will occasionally print null and then terminate or it will instead print "Name:Name:Name:Name:Nam" or other such unpredictable errors. 在传递名称字符串时,在打印列表时,它有时会打印为null,然后终止,或者打印“ Name:Name:Name:Name:Nam”或其他此类不可预测的错误。 Any other comments or criticisms would be appreciated as well as I am just starting to learn the language, thanks. 任何其他评论或批评都将不胜感激,同时我也正开始学习该语言,谢谢。

#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;
    }
}

When you define a pointer like char *name; 当您定义类似char *name;的指针时char *name; it points to some random location as you haven't initialized it. 它指向某个随机位置,因为您尚未初始化它。 It is illegal to write to the pointer and doing so will invoke Undefined Behavior. 写入指针是非法的,这样做会调用未定义行为。

strcpy basically writes the string to this random pointer location invoking UB. strcpy基本上将字符串写入此调用UB的随机指针位置。
strdup on the other hand, allocates the required memory dynamically for the string, copies the string to that location and then returns the start of the location. 另一方面, strdup为该字符串动态分配所需的内存,将字符串复制到该位置,然后返回该位置的开始。 You can read/write to this memory location and hence, this is valid. 您可以读/写该存储位置,因此这是有效的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM