如何安全记忆?

时间:2011-12-27 00:55:12

标签: c string wrapper

我想实际使用这个包装器,但问题是我不知道它是否非常安全。

关于使用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 个答案:

答案 0 :(得分:5)

很多错误:

  

这样安全吗?如果是的话,如果我这样做会发生什么:

没有

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两次,那是不是很糟糕?初始化器会更好吗?

你泄漏记忆。
第二个调用基本上生成一个新对象,旧对象丢失并泄漏。

str_init中的问题

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