Segmentation Fault occurring when accessing the same memory in one function instead of another - c

I am implementing a LinkedList with a bunch of ListNodes that are structs which contain some basic information about people. I have two files, one that is main.c, and another that is main.h. Whenever I attempt to print the list by passing the root to a function, I get an error.
Here is 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;
}
In my main.h file, I have no problem printing attributes of the root parameter in the function "userLoop", but as soon as I pass ListNode *root to "print" or "stuff" I get a seg fault when trying to print its values.
Here is 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;
}
}
}
When printing the address in memory of root in both functions, I get the same value, so I'm not sure why I am unable to access the values in root in one function instead of the other.
Thank you so much for any help.

You don't seem to quite grasp how the memory model works in C. Your offending piece of code is probably:
ListNode *newNode = malloc(sizeof(ListNode));
newNode = &toReturn;
return newNode;
This returns a pointer to the local variable toReturn, not the malloc'd memory address. You need to copy the data from toReturn into your malloc'd memory space. However, even worse you don't malloc space for each of your strings, so each of your nodes point to the same input buffer. This should work, since you malloc with for every node, however if
you are going to start deleting nodes managing your memory is going to be a little awkward. You also don't make sure there is enough room in your buffer.
I suggest looking at some online resources (or ideally a book) to refresh on how C memory works.
Edit: I did not learn C online, but a quick google search turned up this, which at a quick glance seems to be a decent resource.
I would recommend looking into book list. I used C Programming A Modern Approach.

I'm going to assume you're on a 64 bit system so that pointers are 8 bytes & integers are 4 bytes. Use %p for pointers, not %u

Related

I cant find the error of my linked list( why is my head pointer moving?)

I have tried so many times to set my head pointer pointing to the first node. At first(in the empty list) it correctly points the first node. But after the first loop, the head pointer points to the newnode linked. Actually now Im quite unsure about my whole code as well.
int main(void){
struct library *head = NULL; //set the head pointer to NULL
int option;
printf("Enter the number:");
while((option = getchar())!= 9){
switch(option){
case '1':
{
char title[1000];
char author[1000];
char subject[1000];
printf("Enter title of the book you want to add:");
scanf("%s",title);
printf("Enter author of the book you want to add:");
scanf("%s",author);
printf("Enter subject of the book you want to add:");
scanf("%s",subject);
add_book(title,author,subject,&head);
printf("successful! and head pointer is pointing to %s\n",head->collection.title);
break;
}
}
}
void add_book(char title[],char author[],char subject[], struct library ** head){
struct library *current;
struct library *newnode = malloc(sizeof(struct library));
newnode->collection.title = title;
newnode->collection.author = author;
newnode->collection.subject = subject; // assigning value inside newnode
newnode->num_books = 0;
newnode->next = NULL; // assign NULL value to the end of newnod
//when the head is NULL which means when the list is empty
if(*head == NULL)
{
current = newnode;
*head = current;
return;
}
else
{
current = *head; //assign the first node to current pointer
//find the last node of the list
while(current->next != NULL)
{
current = current->next;
}
current->next = newnode; // link the last node to new node
return;
}
}
This is struct for this
struct book {
char* title;
char* author;
char* subject;
};
struct library {
struct book collection;
int num_books;
struct library* next;
};
The lifetime of char title[1000];, char author[1000];, and char subject[1000]; ends when execution reaches the end of the block inside case '1': { /* ... */ }. Once this happens, the pointers that were assigned in add_book become dangling pointers - pointing to invalid memory.
To remedy this, you must ensure the lifetime of your strings matches the lifetime of the structures that contain them. This can be done either by allocating enough space in the structure itself
struct book {
char title[1000];
/* etc. */
};
or by dynamically allocating enough space for a copy of each string. In any case you must copy the string to this memory (man 3 strcpy).
If it is available on your system, man 3 strdup does both steps of the second form at once. Otherwise, it is roughly the same as strcpy(malloc(strlen(source_string) + 1), source_string);.
Also note that the scanf specifier %s is as dangerous as gets when used without a field-width specifier (e.g., char buffer[1000]; scanf("%999s", buffer);), as it can potentially overflow your buffer.
An example program. Enter strings one-by-one, and terminate with EOF CTRL+D (Windows: CTRL+Z, RETURN).
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct link {
char *string;
/* alternatively: char string[512]; */
struct link *next;
};
void add_link(struct link **root, const char *string) {
struct link *node = calloc(1, sizeof *node);
node->string = strdup(string);
/* alternatively: strcpy(node->string, string) */
if (*root) {
struct link *tail = *root;
while (tail->next)
tail = tail->next;
tail->next = node;
} else
*root = node;
}
int main(void) {
struct link *head = NULL;
while (1) {
char buffer[512];
if (!fgets(buffer, sizeof buffer, stdin))
break;
/* remove newline */
buffer[strcspn(buffer, "\n")] = '\0';
add_link(&head, buffer);
}
for (struct link *node = head, *next; node; node = next) {
next = node->next;
printf("STRING: %s\n", node->string);
free(node->string);
free(node);
}
}
Note: in a real program you should always check the return values of your memory allocating functions (malloc, calloc, strdup, etc.) as they can fail.

Could the improper assignment of my singly linked list be leading to an uninitialized value somewhere?

Hello and thanks to all who bothered to read! I am currently working on a program that uses a singly linked list to print out a pattern based on the first letter of the color element and first element in the details int address array shown below.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct Node{
char* color;
int** details;
struct Node* next;
}Node;
Node* light_info(char *filename){
Node* head = malloc(sizeof(Node));
Node* second = malloc(sizeof(Node));
Node* third = malloc(sizeof(Node));
Node* fourth = malloc(sizeof(Node));
Node* fifth = malloc(sizeof(Node));
Node* sixth = malloc(sizeof(Node));
head->next = second;
second->next = third;
third->next = fourth;
fourth->next = fifth;
fifth->next = sixth;
sixth->next = NULL;
FILE* fp = fopen(filename, "r");
char* token;
int num1, num2;
int* ptr1 = &num1;
int* ptr2 = &num2;
char line[250];
Node* current = head;
if(head==NULL||second==NULL||third==NULL||fourth==NULL||fifth==NULL||sixth==NULL){
printf("Error. Program has amnesia, not allocating memory...");
}
else{
while((fgets(line,250,fp)!=NULL)&&(current!=NULL)){
token = strtok(line, ",\n");
current->color = malloc(20);
current->color = token;
current->details = malloc(sizeof(ptr1)*2);
token = strtok(NULL, ",\n");
num1 = atoi(token);
current->details[0]=ptr1;
token = strtok(NULL, ",\n");
num2 = atoi(token);
current->details[1]=ptr2;
current = current->next;
}
}
return head;
}
/*Takes a Node pointer as a parameter, and iterates through the linked list,
printing out a number of dashes for each light's brightness score.*/
void off(Node* h){
printf("\n***Turning lights off:\n");
while(h!=NULL){
int i;
int* ptr = h->details[0];
int b = *ptr;
for(i=0;i<b;i++){
printf("-");
}
printf(" ");
h=h->next;
}
printf("\n");
}
/*Takes a Node pointer as a parameter, and iterates through the linked list,
printing out the first letter of each color the amount of times each light is bright.*/
void on(Node* h){
printf("\n***Turning lights on:\n");
while(h!=NULL){
int i;
int* ptr = h->details[0];
int b = *ptr;
for(i=0;i<b;i++){
printf("%c",h->color[0]);
}
printf(" ");
h=h->next;
}
printf("\n");
}
/*Frees data using Node's head and prints exit message.*/
void Exit(Node* h){
printf("Exiting...\n");
Node* temp;
while(h!=NULL){
free(h->color);
free(h->details);
temp = h;
h = h->next;
free(temp);
}
}
int main(int argc, char **argv){
if(argc < 2||argc >= 3){
printf("Error. Enter one filename and one filename only.");
}
else{
char* filename = argv[1];
Node* head = light_info(filename);
int vibe_check = 1;
int Switch = 0;
char resp[10];
while(vibe_check){
if(head == NULL){
printf("Head memory not allocated...");
vibe_check = 0;
}
else{
scanf("%s", resp);
if(strcmp(resp,"off")==0){
if(Switch==0){
printf("\n--Lights are already off.\n");
}
else{
Switch = 0;
off(head);
}
}
else if(strcmp(resp,"on")==0){
if(Switch==1){
printf("\n--Lights are already on.\n");
}
else{
Switch = 1;
on(head);
}
}
else if(strcmp(resp,"exit")==0){
Exit(head);
}
else{
printf("Invalid command, type in off, on, or exit.");
}
}
}
}
}
The data for this program comes from a file formatted like so,
blue,2,0
green,1,0
red,1,0
red,2,1
yellow,2,1
blue,1,1
The expected out put for the program should be bb g r rr yy b any time someone types on with dashes replacing letters when someone types off after the lights are on. However, when run the program prints nothing out and after several rounds of debugging and valgrind, I've noticed two things:
The Node structs are not assigned line-by-line, leading to Nodes having duplicates of the last line
of data gotten rather than individual pieces of data based on the line read.
According to valgrind, their is an uninitialized value in the on function that I can't find.
Sorry if this is quite lengthy, but any help would be deeply appreciated! I am open to editing my post and any constructive critique if necessary!
The way you process your input in light_info has several errors.
First, current->color is assigned some allocated memory, then that memory is lost by the assignment on the next line (current->color = token;). This assignment will not copy the string pointed to by token, but will change the value of color to point to the same place - which is in the local variable line and will be dangling once your function returns. You'll want to use strcpy (or the safer version, strncpy) to copy the string into your allocated space.
You do something similar with current->details[0]=ptr1;. ptr1 points at the local num1 variable, so this pointer will also become dangling when the function returns. I'm not sure why details is an array of pointers. An array of int (where you can store the values directly) would seem a better choice. (The same applies to details[1] and ptr2).
Unrelated to this problem, the error checks for one of the mallocs to have failed are in the wrong place. You've already dereferenced all those pointers before you check them for NULL. That check should be up right after you've done the last malloc, before you start assigning all those next pointers.
There is also a lack of error checking elsewhere.

Inserting Node Linked List C

I am trying to create a linked list which stores name and age of a student.
I am having trouble with insertion.
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <stdlib.h>
typedef struct node{
char Name[50];
int studentAge;
struct node* next;
}MyNode;
this is how i defined my Struct which constains the requried data and a pointer 'next' which points to the next node.
Below is my insertion function
so in the first if condition i am saying if there isnt a head ie head = NULL then create memory space for the head using malloc.. after this i copy all the data into the head node and making sure that the next of head points to null.
In the second condition i am saying if there is a head ie Head ! = NULL
then traverse the list to the end using the current pointer and then copy all the data in.
void InsertStudent(char givenName[50], int age, MyNode* head){
if(head == NULL){
head = (MyNode*) malloc(sizeof(MyNode));
strcpy(head->Name,givenName);
head->studentAge = age;
head->next = NULL;
}
if(head != NULL){
MyNode* current = head;
while(current->next != NULL){
current = current->next;
}
current->next = (MyNode*) malloc(sizeof(MyNode));
strcpy(current->next->Name,givenName);
current->next->studentAge = age;
current->next->next = NULL;
}
}
Now i am not sure if there is a problem in my printing or inserting because it doesn't print my nodes when i try the code out
void PrintList(MyNode* head){
MyNode* current = head;
while(current != NULL){
printf("Name is %s Age is %d\n",current->Name,current->studentAge);
current = current->next;
}
}
this is my main function.. is there a problem with the MyNode* head = NULL; line of code is that allowed?
int main()
{
MyNode* head = NULL;
int r = 0;
while(r!=1)
{
printf("Data Structures - Linked List\n");
printf("Choose one Option:\n\n");
printf("1.Insert Student\n");
printf("2.Remove Student\n");
printf("3.Print all student\n");
printf("4.Exit\n");
int option=0;
char givenName[50];
int givenAge;
scanf("%d",&option);
switch(option){
case 1:
printf("Enter name of student: ");
scanf("%s",givenName);
printf("\nEnter Age of student: ");
scanf("%d",&givenAge);
InsertStudent(givenName,givenAge,head);
break;
case 2:
printf("Enter name of student: ");
scanf("%s",givenName);
printf("\nEnter Age of student: ");
scanf("%d",&givenAge);
RemoveStudent(givenName,givenAge);
break;
case 3:
PrintList(head);
break;
case 4:
r=1;
break;
default:
r=1;
printf("\nNot an option\n");
break;
}
}
}
You're not setting the initial value of the head pointer to the first node, and since that is never done, the list remains empty and you leak memory like a sieve leaks rain water.
As you have communicated you want to use pointer-to-pointer syntax, the result should look like this . (sans error checking, which you shoudl probably consider adding):
void InsertStudent(char givenName[50], int age, MyNode** head)
{
while (*head)
head = &(*head)->next;
*head = malloc(sizeof **head);
strcpy((*head)->Name, givenName);
(*head)->studentAge = age;
(*head)->next = NULL;
}
Invoked from your main program using the address of the head pointer (do NOT confused that with the address held in the head pointer which you're initially setting to NULL correctly; think of the latter a value held by a pointer, the former as a residence where the head pointer itself is in memory).
InsertStudent(givenName,givenAge, &head); // NOTE THIS
I leave the task of removal and list cleanup.
You are passing head by value; which means that the line in InsertStudent:
head = (MyNode*) malloc(sizeof(MyNode))
which does not update the variable ‘head’ in main.
What you want is to pass &head to InsertStudent, but then InsertStudent has to deal with a MyNode **. The other option is have InsertStudent return head, so that its invocation is:
head = InsertStudent(name, age, head);
It doesn’t matter much either way, some people prefer the latter because it looks more functional.
Inside of InsertStudent, you add the first element twice. This is almost certainly unwanted. By the time you get to the line:
if(head != NULL){
head is never NULL; if it were, you would have assigned it in the if statement above. You probably want this statement to be:
else {

Adding node to a linked list

So I'm creating a linked list in C and adding some nodes to it that contain information. I have an if else statement where I create the linked list's head and then add nodes to it. The problem is that when I add a new node I seem to lose the old one. Not sure why this is happening or how to fix this.
Edit: I have made some updates to make it a runnable program.
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<stdint.h>
#include<regex.h>
int main(int argc, char argv[]) {
int head=0, i=0;
char tempCourseID[10], tempCourseGrade[10], tempCourseCH[10];
static struct LinkedList {
char *CourseName;
char *CourseGrade;
char *CourseCreditHours;
struct LinkedList *next;
} LinkedList;
static struct LinkedList *first, *savefirst, *headlist;
first = malloc(sizeof ((*first)));
savefirst = first;
headlist = first;
for(i ; i<5; i++){
printf("Enter Course name");
fgets(tempCourseID, sizeof(tempCourseID), stdin);
printf("Enter Course grade");
fgets(tempCourseGrade, sizeof(tempCourseGrade), stdin);
printf("Enter Course credit hours");
fgets(tempCourseCH, sizeof(tempCourseCH), stdin);
//checks to see if linked list head exists
if (head == 0) {
printf("No head has been found.\n");
headlist->CourseName = tempCourseID;
headlist->CourseGrade = tempCourseGrade;
headlist->CourseCreditHours = tempCourseCH;
headlist->next = NULL;
printf("A head has been created\n");
printf("A node has been added\n");
head = 1;
} else {
printf("Ahead already exists\n");
first = malloc(sizeof ((*first)));
first->CourseName = tempCourseID;
first->CourseGrade = tempCourseGrade;
first->CourseCreditHours = tempCourseCH;
first->next = NULL;
savefirst->next = first;
savefirst = first;
printf("A node has been add\n");
head = 1;
}
}
while (headlist != NULL) {
printf(" %s ", headlist->CourseName);
printf(" %s ", headlist->CourseGrade);
printf("%s \n", headlist->CourseCreditHours);
headlist = headlist->next;
}
return 0;
}
You have char tempCourseID[10] and char* CourseName
It is legal to use CourseName = tempCourseID; however tempCourseID is temporary, and so the string will be lost soon. In this case we need to allocate separate memory for CourseName, and then copy the value from tempCourseID
Use instead
CourseName = malloc(strlen(tempCourseID) + 1);//add +1 for null-character
strcpy(CourseName, tempCourseID);
//or
CourseName = strdup(tempCourseID)//shortcut!
There are problem with the linked list. You have too many variables with similar names. A linked list needs only head. You can introduce a temporary variable node for adding new nodes. If you are adding nodes to the tail, then save the last node in the list, lets call it savenode
In this example I removed fgets functions and replaced it with sprintf, that's just to make it easier to run the program and debug. You can put back fgets later.
int main(int argc, char argv[])
{
struct LinkedList
{
char *CourseName;
char *CourseGrade;
char *CourseCreditHours;
struct LinkedList *next;
};
int i;
char tempCourseName[100], tempCourseGrade[100], tempCourseCH[100];
struct LinkedList *head = NULL;
struct LinkedList *node = NULL;
struct LinkedList *savenode = NULL;
for(i = 0; i < 5; i++)
{
sprintf(tempCourseName, "CourseName %d", i);
sprintf(tempCourseGrade, "tempCourseGrade %d", i);
sprintf(tempCourseCH, "tempCourseCH %d", i);
node = malloc(sizeof(*node));
node->CourseName = strdup(tempCourseName);
node->CourseGrade = strdup(tempCourseGrade);
node->CourseCreditHours = strdup(tempCourseCH);
node->next = NULL;
if(head == NULL)
head = node;
//check savenode exists
//this will be the last node (tail) in the existing list
//get it to point to our new node
if(savenode)
savenode->next = node;
//now we have a new tail
savenode = node;
}
//walk through the list
node = head;
while(node)
{
printf("%s, %s, %s\n",
node->CourseName, node->CourseGrade, node->CourseCreditHours);
node = node->next;
}
return 0;
}

Insert Node into BST on a loop in C

I'm trying to insert into my BST but I'm struggling with creating a loop out of it.
The code works when I insert one by one, but when I try to put it into a loop it doesn't insert correctly.
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h> // for strcmp()
#include <ctype.h> // for toupper()
typedef struct BstNode{
//char name[20];
// int data;
struct BstNode* left;
struct BstNode* right;
char* name;
}BstNode;
typedef int (*Compare)(const char*, const char*); // makes comparisons easier
/* Returns pointer address to newly created node */
BstNode* createNode(char* name){
BstNode* newNode = (BstNode*)malloc(sizeof(BstNode)); // Allocates memory for the newNode
newNode->name = name; // newNode->data is like newNode.data
newNode->left= NULL;
newNode->right = NULL;
return newNode;
}
//insert node into Tree recursively
BstNode* insertNode(BstNode* node, char* name, Compare cmp){
int i;
/* char *s1 = node->name;
char *s2 = name;
printf("s1: %s, s2: %s\n", s1,s2);
i = strcmp(s1, s2); // if =1, s1 is greater
printf("i: %d\n", i); */
if(node == NULL){// if tree is empty
// printf("inside NULL\n");
node = createNode(name);
//return node;
}
else{
i = cmp (name, node->name); // sweet
if(i == -1){
// printf("inside left\n");
node->left = insertNode(node->left, name, cmp);
//return node;
}
else if(i == 1){
// printf("inside right\n");
node->right = insertNode(node->right, name, cmp);
//return node;
}
else if(i == 0 ){ //avoid duplicates for now
// printf("inside 0\n");
printf("Name is in BST\n");
return NULL;
}
}
return node;
}
BstNode* printTree(BstNode* node){
if(node == NULL){
return NULL;
}
printTree(node->left);
printf("%s\n",node->name);
printTree(node->right);
}
int CmpStr(const char* a, const char* b){
return (strcmp (a, b)); // string comparison instead of pointer comparison
}
//void Insert(Person *root, char name[20]);
int main(){
BstNode* root = NULL; // pointer to the root of the tree
char buf[100];
char option = 'a';
while(1) {
printf("Enter employee name");
scanf("%s",buf);
printf ("Inserting %s\n", buf);
root = insertNode(root, buf, (Compare)CmpStr);
printTree(root);
}
}
I can do root = insertNode(root, name, (Compare)CmpStr)
several times in code, but if I try to loop it with user input it won't insert correctly. I'm not sure if it has to do with the fact that I'm using scanf() or root not being set correctly. I've tried using fgets() as well but I'm not too sure how to use it and keep messing that up.
Any help is appreciated.
In your loop, you always pass the same buffer to your insert function; Your createNode does not copy the content of the buffer but rather stores a reference to the (always) same buffer; Hence, changing the buffer content after insert will also change the "content" of previously inserted nodes.
I'd suggest to replace newNode->name = name in createNode with newNode->name = strdup(name). This will actually copy the passed "contents" and gives your BST control over the memory to be kept. Thereby don't forget to free this memory when deleting nodes later on.

Resources