Как быть в безопасности с памятью? - PullRequest
0 голосов
/ 27 декабря 2011

Я бы хотел использовать эту обертку, но проблема в том, что я пока не знаю, насколько она безопасна.

У меня есть несколько простых вопросов по поводу использования malloc(), calloc()realloc().Вот что у меня есть:

string.h

typedef struct str str; // pointer for encapsulation

string.c

struct str
{
    char *buf;
    size_t len;
}

Скажем, у меня есть вспомогательная функция, которая просто делает это:

    str *NEW_STRING()
    {
        str *temp = calloc(1, sizeof (struct str));
        temp->len = 0;
        temp->buf = (char *) malloc(1);
        return temp;
    }

Это безопасно?Если это так, что произойдет, если я сделаю что-то вроде этого:

str *A_STRING = NEW_STRING();
A_STRING = NEW_STRING();

Это вызвало бы malloc и calloc дважды, это плохо?Будет ли инициализатор лучше?

void str_init(str *A_STRING)
{
    if (A_STRING)
    {
        free(A_STRING);
    }

    if (A_STRING->buf)
    {
        free(A_STRING->buf);
    }

    A_STRING = calloc(1, sizeof (struct str));
    A_STRING->buf = (char *) malloc(1);
    A_STRING->len = 0;
}

Наконец, это хороший способ освободить память?

    void free_string(str *A_STRING)
    {
        if (A_STRING->buf)
        {
            free(A_STRING->buf);
        }
        else
        {
            A_STRING->buf = NULL;
        }

        if (A_STRING)
        {
            free(A_STRING);
        }
        else
        {
            A_STRING = NULL;
        }

        A_STRING->len = 0;
    }

Любая дополнительная информация будет полезна, если она будет включена.Я не хочу ничего публиковать, как если бы это была хорошая библиотека, потому что я делаю это в первую очередь в учебных целях.

1 Ответ

5 голосов
/ 27 декабря 2011

Много ошибок:

это безопасно?если это так, что произойдет, если я сделаю что-то вроде этого:

Нет.

str *NEW_STRING()
{
    str *temp = calloc(1, sizeof (struct str));

    // If calloc fails and returns NULL all the code below is invalid and blows the code up.

Далее:

это вызовет malloc иCalloc дважды, это плохо?будет ли инициализатор лучше?

Вы теряете память.
Второй вызов в основном генерирует новый объект, старый объект теряется и утекает.

void str_init(str *A_STRING)
{

Это первый раз, когда его метод вызывается?
Если так, то A_STRING содержит случайное значение (которое вы собираетесь БЕСПЛАТНО).
Это взорвет код.

    if (A_STRING)
    {
        free(A_STRING);
    }

A_STRING освобожден (теперь вы больше не можете к нему обращаться).
Любой код, который делает это, является плохим.

    if (A_STRING->buf)   // Bang blow up code.
    {
        free(A_STRING->buf);
    }

    A_STRING = calloc(1, sizeof (struct str));

Нет проверки результата calloc.

    A_STRING->buf = (char *) malloc(1);
    A_STRING->len = 0;
}

это хороший способ освободить память?

void free_string(str *A_STRING)
{
    if (A_STRING->buf)
    {
        free(A_STRING->buf);
    }
    else
    {
        A_STRING->buf = NULL;  // Its already NULL pointless work
    }

    if (A_STRING)
    {
        free(A_STRING);
    }
    else
    {
        A_STRING = NULL;  // ITs already NULL pointless work
    }

    // BANG you just blew up the space shuttle.
    A_STRING->len = 0;
}
...