【问题标题】:const char* and free()const char* 和 free()
【发布时间】:2012-06-15 19:50:31
【问题描述】:

鉴于下一个代码示例,我无法释放参数const char* expression

// removes whitespace from a characterarray
char* removewhitespace(const char* expression, int length)
{
    int i = 0, j = 0;
    char* filtered;
    filtered = (char*)malloc(sizeof(char) * length);
    while(*(expression + i) != '\0')
    {
        if(!(*(expression + i) == ' '))
        {
            *(filtered + j) = *(expression + i);
            j++;
        }
        i++;
    }
    filtered[j] = '\0';
    free(expression); //this doesn't seem to work
    return filtered;
}

在返回此函数之前,我尝试释放表达式参数中的数据,但似乎无法释放它。
我认为这可能是因为它是一个常量,但我了解到 C 中的字符数组始终应该是一个常量。

我收到的错误消息在free(expression) 行,消息是:
expected void* but argument is of type const char * - compiler error

如何丢弃数据expression包含的内存?

【问题讨论】:

  • “不起作用”是什么意思?编译器错误?运行时错误?从用户的鼻子里冒出来的守护进程?
  • “似乎不起作用”和“无法释放”是什么意思?
  • 免费(表达式);期望 void* 但参数的类型为 const char*
  • 释放和非 malloc'd、realloc'd 或 calloc'd 指针是未定义的行为。
  • 你尝试释放expression,但是如果已经分配在堆栈上,或者一个字符串字面量呢?您应该让调用者决定如何处理它。

标签: c memory-management free character-arrays


【解决方案1】:

如果它是一个常量,这意味着它不应该被删除,因为它没有被分配:调用者可以很容易地将一个基于堆栈的数组传递给你的方法,并且释放它会是一个错误事情

最常见的约定是任何分配数据的代码都应该释放数据。消除这种争论真的不是你的例行公事的责任,因为它无法知道这是否是合法的事情。

【讨论】:

  • 如果它是函数定义(分别由其文档)提出的“合同”的一部分,那没关系。但是调用者应该意识到这一点,并且应该有很好的文档记录,甚至可能在函数名本身中有提示。
  • @glglgl 总的来说,我有点同意。问题在于这种情况const 隐含并由编译器强制执行的合同是expression 不会以任何方式改变形状或形式。正如 Ernest 所说,试图使用文档来规避语言规范绝对是一件非常糟糕的事情
【解决方案2】:

如果你真的想要一个这样的函数——获取一个堆指针,释放它,尽管返回另一个堆指针——你应该很好地记录它。

此外,您不应该将expression 设为const char*,因为这不匹配,如您所见。不过char* 应该没问题。

【讨论】:

    【解决方案3】:

    直接直接回答问题是 free((void*)expression); 这应该足以解决编译错误。 但是,正如其他人已经声明的那样,您应该让调用您的函数的人来管理内存

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-01-08
      • 2013-03-20
      • 1970-01-01
      • 1970-01-01
      • 2013-04-23
      • 1970-01-01
      • 2018-11-05
      • 2010-10-27
      相关资源
      最近更新 更多