【问题标题】:How to be safe with memory?如何确保内存安全?
【发布时间】:2011-12-27 00:55:12
【问题描述】:

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

我有几个关于使用malloc()calloc()realloc() 的简单问题。这是我到目前为止所拥有的:

字符串.h

typedef struct str str; // pointer for encapsulation

字符串.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;
    }

如果包含任何其他信息,将会非常有用。我不想向公众发布任何东西,就好像它是一个好的图书馆一样,因为我这样做主要是为了学习。

【问题讨论】:

  • 如果没有 C++,你真的无能为力。
  • 在你的第二个代码 sn-p 中,temp 没有检查分配失败
  • 您正在访问刚刚在str_init() 中释放的内存...这不是一个好的开始。
  • 不要这样做。你已经有了 C-Stirings。这些问题是已知的,人们可以解决这些问题。引入另一个 C-String 库会适得其反,您将引入一组全新的问题而不会增加任何实际价值。
  • 我会推荐一本关于 C 的初学者书籍。特别是关于 malloc()free() / 内存管理的部分。天下没有免费的午餐,你需要留意它。

标签: c string wrapper


【解决方案1】:

很多错误:

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

没有。

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

【讨论】:

  • free_string() 函数中,您应该在执行任何其他操作之前检查if (A_STRING)。当您(OP)检查它时,如果它为空,则程序在 if (A_STRING->buf) 上爆炸。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-02
  • 1970-01-01
相关资源
最近更新 更多