What's wrong here? [dynamic structures C]
I'm trying this code, it's works sometimes, but sometimes it doesn't works fine! I created a function that returns a pointer to an struct and then I create a function (Add) that adds words in to a new struct.
typedef int boolean;
boolean first = TRUE;
typedef struct s_Reg
{
char *str;
struct s_Reg *next;
} Reg;
Reg* CreateList()
{
Reg *list = (Reg*)malloc(sizeof(Reg));
list -> str = (char*)malloc(sizeof(char));
if (list != NULL && list -> str)
return list;
else
return NULL;
}
boolean Add(Reg *list, char *str)
{
Reg *pos = list;
if (first == TRUE)
{
list -> str = (char*)malloc(sizeof(char));
if (list -> str != NULL)
{
list -> str = str;
list -> next = NULL;
first = FALSE;
}
else
return FALSE;
}
else
{
while (pos -> next != NULL)
pos = pos -> next;
pos -> next = (Reg*)malloc(sizeof(Reg));
if (pos -> next != NULL)
{
pos = pos -> next;
pos -> str = (char*)malloc(sizeof(char));
开发者_如何学Python if (pos -> str != NULL)
{
pos -> str = str;
pos -> next = NULL;
}
else
return FALSE;
}
else
return FALSE;
}
return TRUE;
}
int main()
{
boolean b;
int i;
char *str;
Reg *words = CreateList();
str = malloc(sizeof(char));
if (words == NULL)
return -1;
for (i = 1; i <= 3; ++i)
{
printf("\nword: ");
gets(str);
b = Add(words, str);
if (b == FALSE)
return -1;
str = malloc(sizeof(char));
}
while (words != NULL)
{
printf("Word: %s\n", words -> str);
words = words -> next;
}
free(str);
str = NULL;
free(words);
words = NULL;
return 0;
}
If i do this (not using FOR to insert data)
Add(words, "blablablablablabla");
Add(words, "blablaasfsafdblblablaasfbla");
Add(words, "blablaasfsafdblblablaasfblaasdfasfasdf");
It works fine everytime! but using FOR to insert data, if i insert a long string, sometimes crash!
/////// **EDIT ////////**
Well, i read all the questions, thank you everybody. I rewrite the code and it seems it works (but i think it can be better)
This is my FINAL? code:
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#define TRUE 1
#define FALSE -1
typedef int boolean;
boolean first = TRUE;
typedef struct s_Reg
{
char *str;
char *str2;
char *str3;
struct s_Reg *next;
} Reg;
Reg* CreateList()
{
Reg *list = (Reg*)malloc(sizeof(Reg));
if (list != NULL)
return list;
else
return NULL;
}
boolean Add(Reg *list, char *str, char *str2, char *str3)
{
Reg *pos = list;
if (first == TRUE)
{
list -> str = (char*)malloc(strlen(str) + 1);
list -> str2 = (char*)malloc(strlen(str2) + 1);
list -> str3 = (char*)malloc(strlen(str3) + 1);
if (list -> str == NULL || list -> str2 == NULL || list -> str3 == NULL)
return FALSE;
sprintf(list -> str, str);
sprintf(list -> str2, str2);
sprintf(list -> str3, str3);
list -> next = NULL;
first = FALSE;
}
else
{
while (pos -> next != NULL)
pos = pos -> next;
pos -> next = (Reg*)malloc(sizeof(Reg));
if (pos -> next != NULL)
{
pos = pos -> next;
pos -> str = (char*)malloc(strlen(str) + 1);
pos -> str2 = (char*)malloc(strlen(str2) + 1);
pos -> str3 = (char*)malloc(strlen(str3) + 1);
if (pos -> str == NULL || pos -> str2 == NULL || pos -> str3 == NULL)
return FALSE;
sprintf(pos -> str, str);
sprintf(pos -> str2, str2);
sprintf(pos -> str3, str3);
pos -> next = NULL;
}
else
return FALSE;
}
return TRUE;
}
int main()
{
boolean b;
int i;
char str[64], str2[64], str3[64];
Reg *words = CreateList();
if (words == NULL)
return -1;
for (i = 1; i <= 3; ++i)
{
printf("\nstr1: ");
gets(str);
printf("\nstr2: ");
gets(str2);
printf("\nstr3: ");
gets(str3);
b = Add(words, str, str2, str3);
if (b == FALSE)
return -1;
}
while (words != NULL)
{
printf("str1: %s\n", words -> str);
printf("str2: %s\n", words -> str2);
printf("str3: %s\n\n", words -> str3);
words = words -> next;
}
free(words);
words = NULL;
return 0;
}
You entire string handling code is wrong. You allocate memory for a single character only. You then leak that memory.
Before tackling code like this you need to go back to basics and learn how to use malloc()
and strncpy()
.
For example, a routine that might help you would be this:
char* AllocStr(char *str)
{
size_t len;
char *result;
len = strlen(str)+1;//add one for zero-terminator
result = malloc(len);
return strncpy(result, str, len);
}
This allocates memory for a new string based on the length of the input parameter, and then copies the contents of the input parameter to the new string.
Every time you assign to the str
field of your struct you need to use code like this.
There are a lot of other bugs in your code but right now I think you need to step back and improve your understanding of pointers, memory allocation/deallocation etc. Can you find a simpler problem to work with because at your current level, trying to debug this code is likely to be very inefficient.
Note: There is no error checking in this sample for ease of exposition.
str = malloc(sizeof(char))
See, You allocate one byte memory. And pass str to gets function, which leads to some undefined behaviors
You have also to review the memory management. Indeed, when you create the list, memory is allocated for string. Then, the Add function is called and will also allocate memory when first == TRUE, this is not correct as already allocated...
精彩评论