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












0















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. The program compiles perfectly yet if I use strcpy() instead of strdup() then I get unwanted output.



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. 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. 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: %snAge: %dnPhoneNumber: %snnn",
temp -> name,
temp -> age,
temp -> phoneNumber);
temp = temp -> next;
}
}









share|improve this question


















  • 1





    OT: for ease of readability and understanding: 1) Please consistently indent the code. Indent after every opening brace '{'. Unindent before every closing brace '}'. Suggest each indent level be 4 spaces.

    – user3629249
    Dec 30 '18 at 21:04






  • 1





    OT: when calling any of the heap allocation functions: malloc calloc realloc 1) in C, the returned type is void* which can be assigned to any pointer. Casting just clutters the code, making it more difficult to understand, debug, etc. I.E. this: newNode = (struct addressBook *) malloc(sizeof(struct addressBook)); should be: newNode = malloc(sizeof(struct addressBook));

    – user3629249
    Dec 30 '18 at 21:06













  • the posted code has a massive memory leak. Every memory allocation 'should' be matched with a call to 'free()` before the program exits. I.E. to do write code that requires the OS to cleanup afterward

    – user3629249
    Dec 30 '18 at 21:08






  • 1





    OT: when calling any of the scanf() family of functions. 1) always check the returned value to assure the operation was successful. 2) when using the input format specifiers: '%s' and/or '%[...]' always use a MAX CHARACTERS modifier that is 1 less than the length of the input buffer because those specifiers always append a NUL byte to the input. This avoid a possibility of a buffer overflow and the resulting undefined behavior

    – user3629249
    Dec 30 '18 at 21:11
















0















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. The program compiles perfectly yet if I use strcpy() instead of strdup() then I get unwanted output.



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. 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. 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: %snAge: %dnPhoneNumber: %snnn",
temp -> name,
temp -> age,
temp -> phoneNumber);
temp = temp -> next;
}
}









share|improve this question


















  • 1





    OT: for ease of readability and understanding: 1) Please consistently indent the code. Indent after every opening brace '{'. Unindent before every closing brace '}'. Suggest each indent level be 4 spaces.

    – user3629249
    Dec 30 '18 at 21:04






  • 1





    OT: when calling any of the heap allocation functions: malloc calloc realloc 1) in C, the returned type is void* which can be assigned to any pointer. Casting just clutters the code, making it more difficult to understand, debug, etc. I.E. this: newNode = (struct addressBook *) malloc(sizeof(struct addressBook)); should be: newNode = malloc(sizeof(struct addressBook));

    – user3629249
    Dec 30 '18 at 21:06













  • the posted code has a massive memory leak. Every memory allocation 'should' be matched with a call to 'free()` before the program exits. I.E. to do write code that requires the OS to cleanup afterward

    – user3629249
    Dec 30 '18 at 21:08






  • 1





    OT: when calling any of the scanf() family of functions. 1) always check the returned value to assure the operation was successful. 2) when using the input format specifiers: '%s' and/or '%[...]' always use a MAX CHARACTERS modifier that is 1 less than the length of the input buffer because those specifiers always append a NUL byte to the input. This avoid a possibility of a buffer overflow and the resulting undefined behavior

    – user3629249
    Dec 30 '18 at 21:11














0












0








0








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. The program compiles perfectly yet if I use strcpy() instead of strdup() then I get unwanted output.



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. 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. 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: %snAge: %dnPhoneNumber: %snnn",
temp -> name,
temp -> age,
temp -> phoneNumber);
temp = temp -> next;
}
}









share|improve this question














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. The program compiles perfectly yet if I use strcpy() instead of strdup() then I get unwanted output.



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. 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. 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: %snAge: %dnPhoneNumber: %snnn",
temp -> name,
temp -> age,
temp -> phoneNumber);
temp = temp -> next;
}
}






c string linked-list






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Dec 29 '18 at 5:53









chak.koppula199chak.koppula199

11




11








  • 1





    OT: for ease of readability and understanding: 1) Please consistently indent the code. Indent after every opening brace '{'. Unindent before every closing brace '}'. Suggest each indent level be 4 spaces.

    – user3629249
    Dec 30 '18 at 21:04






  • 1





    OT: when calling any of the heap allocation functions: malloc calloc realloc 1) in C, the returned type is void* which can be assigned to any pointer. Casting just clutters the code, making it more difficult to understand, debug, etc. I.E. this: newNode = (struct addressBook *) malloc(sizeof(struct addressBook)); should be: newNode = malloc(sizeof(struct addressBook));

    – user3629249
    Dec 30 '18 at 21:06













  • the posted code has a massive memory leak. Every memory allocation 'should' be matched with a call to 'free()` before the program exits. I.E. to do write code that requires the OS to cleanup afterward

    – user3629249
    Dec 30 '18 at 21:08






  • 1





    OT: when calling any of the scanf() family of functions. 1) always check the returned value to assure the operation was successful. 2) when using the input format specifiers: '%s' and/or '%[...]' always use a MAX CHARACTERS modifier that is 1 less than the length of the input buffer because those specifiers always append a NUL byte to the input. This avoid a possibility of a buffer overflow and the resulting undefined behavior

    – user3629249
    Dec 30 '18 at 21:11














  • 1





    OT: for ease of readability and understanding: 1) Please consistently indent the code. Indent after every opening brace '{'. Unindent before every closing brace '}'. Suggest each indent level be 4 spaces.

    – user3629249
    Dec 30 '18 at 21:04






  • 1





    OT: when calling any of the heap allocation functions: malloc calloc realloc 1) in C, the returned type is void* which can be assigned to any pointer. Casting just clutters the code, making it more difficult to understand, debug, etc. I.E. this: newNode = (struct addressBook *) malloc(sizeof(struct addressBook)); should be: newNode = malloc(sizeof(struct addressBook));

    – user3629249
    Dec 30 '18 at 21:06













  • the posted code has a massive memory leak. Every memory allocation 'should' be matched with a call to 'free()` before the program exits. I.E. to do write code that requires the OS to cleanup afterward

    – user3629249
    Dec 30 '18 at 21:08






  • 1





    OT: when calling any of the scanf() family of functions. 1) always check the returned value to assure the operation was successful. 2) when using the input format specifiers: '%s' and/or '%[...]' always use a MAX CHARACTERS modifier that is 1 less than the length of the input buffer because those specifiers always append a NUL byte to the input. This avoid a possibility of a buffer overflow and the resulting undefined behavior

    – user3629249
    Dec 30 '18 at 21:11








1




1





OT: for ease of readability and understanding: 1) Please consistently indent the code. Indent after every opening brace '{'. Unindent before every closing brace '}'. Suggest each indent level be 4 spaces.

– user3629249
Dec 30 '18 at 21:04





OT: for ease of readability and understanding: 1) Please consistently indent the code. Indent after every opening brace '{'. Unindent before every closing brace '}'. Suggest each indent level be 4 spaces.

– user3629249
Dec 30 '18 at 21:04




1




1





OT: when calling any of the heap allocation functions: malloc calloc realloc 1) in C, the returned type is void* which can be assigned to any pointer. Casting just clutters the code, making it more difficult to understand, debug, etc. I.E. this: newNode = (struct addressBook *) malloc(sizeof(struct addressBook)); should be: newNode = malloc(sizeof(struct addressBook));

– user3629249
Dec 30 '18 at 21:06







OT: when calling any of the heap allocation functions: malloc calloc realloc 1) in C, the returned type is void* which can be assigned to any pointer. Casting just clutters the code, making it more difficult to understand, debug, etc. I.E. this: newNode = (struct addressBook *) malloc(sizeof(struct addressBook)); should be: newNode = malloc(sizeof(struct addressBook));

– user3629249
Dec 30 '18 at 21:06















the posted code has a massive memory leak. Every memory allocation 'should' be matched with a call to 'free()` before the program exits. I.E. to do write code that requires the OS to cleanup afterward

– user3629249
Dec 30 '18 at 21:08





the posted code has a massive memory leak. Every memory allocation 'should' be matched with a call to 'free()` before the program exits. I.E. to do write code that requires the OS to cleanup afterward

– user3629249
Dec 30 '18 at 21:08




1




1





OT: when calling any of the scanf() family of functions. 1) always check the returned value to assure the operation was successful. 2) when using the input format specifiers: '%s' and/or '%[...]' always use a MAX CHARACTERS modifier that is 1 less than the length of the input buffer because those specifiers always append a NUL byte to the input. This avoid a possibility of a buffer overflow and the resulting undefined behavior

– user3629249
Dec 30 '18 at 21:11





OT: when calling any of the scanf() family of functions. 1) always check the returned value to assure the operation was successful. 2) when using the input format specifiers: '%s' and/or '%[...]' always use a MAX CHARACTERS modifier that is 1 less than the length of the input buffer because those specifiers always append a NUL byte to the input. This avoid a possibility of a buffer overflow and the resulting undefined behavior

– user3629249
Dec 30 '18 at 21:11












1 Answer
1






active

oldest

votes


















6














When you define a pointer like 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.
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. You can read/write to this memory location and hence, this is valid.






share|improve this answer
























  • Makes perfect sense, thank you so much!

    – chak.koppula199
    Dec 29 '18 at 13:41











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53967081%2fwhy-does-the-strcpy-function-produce-unwanted-outputs-in-the-case-of-this-prog%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









6














When you define a pointer like 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.
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. You can read/write to this memory location and hence, this is valid.






share|improve this answer
























  • Makes perfect sense, thank you so much!

    – chak.koppula199
    Dec 29 '18 at 13:41
















6














When you define a pointer like 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.
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. You can read/write to this memory location and hence, this is valid.






share|improve this answer
























  • Makes perfect sense, thank you so much!

    – chak.koppula199
    Dec 29 '18 at 13:41














6












6








6







When you define a pointer like 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.
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. You can read/write to this memory location and hence, this is valid.






share|improve this answer













When you define a pointer like 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.
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. You can read/write to this memory location and hence, this is valid.







share|improve this answer












share|improve this answer



share|improve this answer










answered Dec 29 '18 at 6:02









SpikatrixSpikatrix

17.4k62660




17.4k62660













  • Makes perfect sense, thank you so much!

    – chak.koppula199
    Dec 29 '18 at 13:41



















  • Makes perfect sense, thank you so much!

    – chak.koppula199
    Dec 29 '18 at 13:41

















Makes perfect sense, thank you so much!

– chak.koppula199
Dec 29 '18 at 13:41





Makes perfect sense, thank you so much!

– chak.koppula199
Dec 29 '18 at 13:41


















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53967081%2fwhy-does-the-strcpy-function-produce-unwanted-outputs-in-the-case-of-this-prog%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Monofisismo

Angular Downloading a file using contenturl with Basic Authentication

Olmecas