Что здесь не так? [динамические структуры C] - PullRequest
0 голосов
/ 01 мая 2011

Я пытаюсь этот код, иногда он работает, но иногда он не работает нормально!Я создал функцию, которая возвращает указатель на структуру, а затем я создаю функцию (Add), которая добавляет слова в новую структуру.

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

Если я делаю это (не используя FOR для вставки данных)

Add(words, "blablablablablabla");
Add(words, "blablaasfsafdblblablaasfbla");
Add(words, "blablaasfsafdblblablaasfblaasdfasfasdf");

Работает нормально каждый раз!но используя FOR для вставки данных, если я вставляю длинную строку, иногда происходит сбой!

/////// ** EDIT //////// **

Ну, я прочитал все вопросы, спасибо всем.Я переписываю код, и кажется, что он работает (но я думаю, что он может быть лучше)

Это мой ФИНАЛ?код:

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

Ответы [ 3 ]

4 голосов
/ 01 мая 2011

Весь код обработки строк неверен.Вы выделяете память только для одного символа.Затем вы теряете эту память.

Прежде чем приступить к такому коду, вам необходимо вернуться к основам и узнать, как использовать malloc() и strncpy().

Например, подпрограмма, которая можетпомочь вам в этом:

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

Это выделяет память для новой строки на основе длины входного параметра, а затем копирует содержимое входного параметра в новую строку.

Каждый раз, когда вы присваиваете поле str вашей структуры, вам нужно использовать такой код:

В вашем коде много других ошибок, но сейчас я думаю, что вам нужно отступить и улучшитьваше понимание указателей, выделения / освобождения памяти и т. д. Можете ли вы найти более простую проблему для работы, потому что на текущем уровне попытка отладки этого кода, вероятно, будет очень неэффективной.

Примечание : В этом образце нет проверки ошибок для простоты изложения.

0 голосов
/ 01 мая 2011

Вы также должны рассмотреть управление памятью.Действительно, когда вы создаете список, память выделяется для строки.Затем вызывается функция Add, которая также выделяет память при первом == TRUE, это не правильно, поскольку уже выделено ...

0 голосов
/ 01 мая 2011
str  = malloc(sizeof(char))

Видите, вы выделяете одну байтовую память. И передать str в функцию gets, что приводит к неопределенному поведению

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...