开发者

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...

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜