无法在C中释放const指针

leg*_*o69 65 c free const

我怎么能免费const char*?我分配了新内存使用malloc,当我试图释放它时,我总是收到错误"不兼容的指针类型"

导致这种情况的代码如下:

char* name="Arnold";
const char* str=(const char*)malloc(strlen(name)+1);

free(str); // error here
Run Code Online (Sandbox Code Playgroud)

Mic*_*zek 82

有几个人发布了正确答案,但由于某种原因,他们一直在删除它.你需要将它转换为非const指针; free需要一个void*,而不是const void*:

free((char*)str);
Run Code Online (Sandbox Code Playgroud)

  • 我记得在Linux内核中读取了一个带有const指针的内存释放函数,有人问Linus为什么,并且他辩护说它实际上没有修改指向的值,无论是在概念上还是在实践中,它只是看起来使用指针启动内存块并释放它.我同意他的评估,因此将free()函数的规范视为不正确.但唉,这是标准. (36认同)
  • 它可以工作,但将`const`转换为非const是代码气味的症状. (18认同)
  • 如果"freeing"在概念上发生了变化,那么可以声明一个`const int`然后离开声明它的范围吗?在释放资源并使其指针不再有效的意义上,"释放"自动变量.这只是一个怪癖,"自由"采用非常数,它不是高处的诫命.在极少数情况下,你的指针只有一件事是非常量的,并且它是免费的,那么实际上你可能从一个const指针(你转为免费)获得比非常量指针更多的好处(你可能会不小心修改). (11认同)
  • 为什么演员表演char*?为什么不直接免费((void*)str)? (8认同)
  • @el。`free()` 是一个例外,因为您可能不希望指针在其生命周期内被修改,但您仍然希望在最后释放它 (2认同)
  • @philippe要么有效,我只是想我会说明问题不是传递免费的 char* 而不是 void* (这是答案之一,尽管我认为它现在已被删除),而是传递 const char*而不是非常量 char*/void* (2认同)
  • @el.当然,但这似乎没必要.我不打算将两个指针保持在同一个地方,一个常量,一个不是,这样我就可以在不使用恶魔的情况下释放非常量的一个 (2认同)
  • 我同意@Hasturkun,你不会收到关于选角的警告;强制转换具体是说“相信我,我想要这种类型的值,而且我不想争论它” (2认同)
  • @JeremyP 我不认为“自由是改变的一种形式”像你想象的那样毫无争议;例如,请参阅 rmeador 的评论 (2认同)
  • @rmeador 8 年多后回答,但众所周知,Linus 在其他情况下对 C 语言的看法也是非常错误的。来自虚假权威的论证。 (2认同)

Tim*_*ost 24

你的代码是颠倒的.

这个:

char* name="Arnold";
const char* str=(const char*)malloc(strlen(name)+1);
Run Code Online (Sandbox Code Playgroud)

应该是这样的:

const char* name="Arnold";
char* str=(char*)malloc(strlen(name)+1);
Run Code Online (Sandbox Code Playgroud)

const存储类型告诉你不打算一次分配(动态,或静态)修改的内存块的编译器.释放内存正在修改它.注意,你不需要转换malloc()的返回值,但这只是一个旁边.

在动态分配内存(你正在做的事情,基于其长度name)并告诉编译器你无意使用它几乎没有用处.注意,使用含义写入内容,然后(可选)稍后释放它.

转换为不同的存储类型并不能解决您将存储类型改为开始的问题:)它只会发出警告消失,它试图告诉您一些事情.

如果代码反转(应该是),free()将按预期工作,因为您实际上可以修改分配的内存.

  • OP询问如何释放指向const限定类型的指针-随附的代码示例反映了他的问题,您的解释与此矛盾。顺便说一句,指向类型的const限定符不会影响或表达对已分配对象本身将执行的操作或意图,它仅影响将通过此指针执行的操作。一次/如果放弃指向常量的限定符,则可以修改分配的对象。 (2认同)

Pau*_*l R 6

malloc指向const的指针是没有意义的,因为你将无法修改其内容(没有丑陋的黑客攻击).

FWIW,gcc只是给出了以下警告:

//
// const.c
//

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    const char *p = malloc(100);

    free(p);
    return 0;
}

$ gcc -Wall const.c -o const
const.c: In function ‘main’:
const.c:8: warning: passing argument 1 of ‘free’ discards qualifiers from pointer target type
$ 
Run Code Online (Sandbox Code Playgroud)

你用的是什么编译器?

  • 这是一个你可能想要释放指针到const的情况:`char const*s = strdup("hello"); 自由(S);`. (10认同)
  • 您可能希望获取一个字符串的副本,该字符串即将被释放()或由库代码更改.您不打算修改副本,因此将其标记为const. (7认同)
  • @bobbogo:是的,虽然很难想象为什么您首先要制作字符串文字的 const 副本。 (2认同)