我怎样才能释放const char*
?我使用分配了新的内存malloc
,当我尝试释放它时,我总是收到错误“不兼容的指针类型”
导致这种情况的代码类似于:
char* name="Arnold";
const char* str=(const char*)malloc(strlen(name)+1);
free(str); // error here
我怎样才能释放const char*
?我使用分配了新的内存malloc
,当我尝试释放它时,我总是收到错误“不兼容的指针类型”
导致这种情况的代码类似于:
char* name="Arnold";
const char* str=(const char*)malloc(strlen(name)+1);
free(str); // error here
void free(const void* p);
。已在C ++中修复(带有delete
)
const char*
。提问者真的需要我们的许可才能遇到问题吗?;-)
str
,就无法通过对其进行更改str
,这意味着它永久性地成为了内存中的所有malloc()
内容。不进行强制复制就无法复制该名称str
。(此外,将字符串文字分配给achar *
也不好,因为尝试修改字符串文字是未定义的行为。我认为您只是将const
s弄混了。)
const char *
您所获取char *
的内容可能已被填充,例如来自const char* foo() { char* s = malloc(...); strcpy(s, ...); return s; }
。
Answers:
有几个人发布了正确的答案,但是由于某些原因,他们一直在删除它。您需要将其强制转换为非const指针;free
需要一个void*
,而不是const void*
:
free((char*)str);
const
转换为非const是代码气味的征兆。
free()
是一个例外,因为您可能不希望在指针的生命周期内对其进行修改,但仍希望在最后将其释放
const int
然后离开声明它的范围了吗?从释放资源并使指向它的指针不再有效的意义上讲,这“释放”了自动变量。这只是一个free
需要使用非常量的怪癖,而不是高尚的诫命。在极少数情况下,您只需要对非const指针做一件事,并且将其释放,那么在实用上,与非const指针(它转换为free)相比,您可能会从const指针(转换为free)中获得更多收益。您可能会意外修改)。
您的代码是反向的。
这个:
char* name="Arnold";
const char* str=(const char*)malloc(strlen(name)+1);
应该看起来像这样:
const char* name="Arnold";
char* str=(char*)malloc(strlen(name)+1);
该const
存储类型告诉编译器,你不打算修改的内存块一次分配(动态,或静态)。释放内存正在对其进行修改。注意,您不需要强制转换malloc()的返回值,但这只是一个问题。
动态分配内存(根据的长度,您正在做的事情name
)并告诉编译器您无意使用它,这几乎没有用。注意,使用含义向其中写入一些内容,然后(可选)稍后释放它。
强制转换为其他存储类型并不能解决以下事实:您从一开始就颠倒了存储类型:)只是警告消失了,它试图告诉您一些信息。
如果代码是反向的(应该正确),free()
则将按预期工作,因为您实际上可以修改分配的内存。
m分配指向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
$
您正在使用什么编译器?
char const* s = strdup("hello"); free(s);
。
在某些情况下,您想释放一个const*
。但是,除非您在同一函数中进行分配/分配,否则您不希望这样做。否则您可能会破坏事情。有关真实示例,请参见下面的代码。我const
在函数声明中使用以表明我没有更改参数的内容。但是,将其重新分配为需要释放的小写副本(strdup)。
char* tolowerstring(const char *to_lower)
{
char* workstring = strdup(to_lower);
for(;workstring != '\0'; workstring++)
*workstring = tolower(workstring);
return workstring;
}
int extension_checker(const char* extension, const char* to_check)
{
char* tail = tolowerstring(to_check);
extension = tolowerstring(extension);
while ( (tail = strstr( tail+1, extension)) ) { /* The +1 prevents infinite loop on multiple matches */
if ( (*extension != '.' ) && ( tail[-1] != '.'))
continue;
if ( tail[strlen(extension)] == '\0') {
free(tail);
free( (char*) extension);
return 1;
}
}
free(tail);
free( (char *) extension);
return 0;
}
将目标的malloc指针强制转换为const是没有目的的。任何使用const指针的函数都不应负责释放传递给它的内存。
struct foo { const char *bar; ... }
呢?这表示了一个事实,即指向的内存foo->bar
应视为不可变的(而的其他成员struct foo
可能是可变的)。这对于确保程序的正确性很有用。bar
首次初始化对象时,可能仍需要进行malloc。如果要释放这样的对象,则也需要一种释放方法bar
。
struct foo { union { const char *bar; char *__bar; }; }
我想会有用的。
有几个答案建议简单地转换为char*
。但正如埃尔·佩斯卡多(El.pescado)上文所述,
强制
const
转换为非-const
是代码异味的症状。
有防止这种情况的编译器警告,例如-Wcast-qual
在gcc中,我发现它非常有用。如果您确实有一个释放const
指针的有效情况(与许多此处编写的情况相反,则有nlstd指出的有效情况),则可以为此目的定义一个宏:
#define free_const(x) free((void*)(long)(x))
这至少对gcc有效。双重-Wcast-qual
强制转换使逻辑不会将其检测为“强制转换常量”。不用说,此宏应谨慎使用。实际上,它仅应用于在同一函数中分配的指针。
我可能错了,但我认为问题出在哪里const
。将指针强制转换为非常量,例如:
free((char *) p);
因为const
您说:不要更改此指针指向的数据。
free
不会更改指针。它释放指针指向的内存块。这是语言规范中的错误。free
应该清楚地带一个const指针。
const
意味着您不能更改存储对象的内容,不能更改指针的实际值...并且释放指向的内存是我要说的一个相当大的变化!(顺便说一句,认为规范是错误的(并且已经有30多年的错误了),似乎有点自命不凡,突然间您发现自己是对的,而所有审核委员会成员都不对,不是吗? )
delete
C ++中的C语言可以在上使用const char*
,因此如果引起很大争议,那么一个或另一组标准作者肯定是错误的。实际上,我认为这并不重要-抛弃const以释放指针几乎不是危机。
const
表示不应更改此位置的数据。但是,如果释放内存,此位置的数据可能会被覆盖并因此被更改。
您不能自由,const char *
因为它是const
。将收到的指针存储malloc
在非const指针变量中,以便可以将它们传递给free
。您可以将char *
参数传递给带有const char *
参数的函数,但相反的情况并不总是正确的。
void foo (const char *x);
char *ptr = malloc (...);
foo (ptr);
free (ptr);
delete
使用const char*
。那你为什么不呢?指针阻止字符被修改的事实,一旦不再需要,就不应不允许删除该字符串。我对C的了解还不够。有人在这里标出报价吗?
free
以任何方式影响您对其的能力。
const
由尝试释放字符串常量引起的。
const char*
。” 我不同意。如果是这样,则永远不要有const
动态分配的字符串,因为您无法删除它们。那真是愚蠢。是否动态分配某些内容以及是否应该更改某些内容是正交的问题。我可以动态分配一些我不想更改的字符串,但是必须在某个时候释放它们。我认为这是C std库中的一个错误,可能是由于const
C后来才从C ++中采用,而现在它有点像个红发继子。
如果您正在谈论纯C并且可以完全控制内存分配,则可以使用以下技巧将(const char *)强制转换为(char *),这在编译器中不会给出任何警告:
const char *const_str = (const char *)malloc(...);
char *str = NULL;
union {
char *mutable_field_p;
const char *const_field_p;
} u;
u.const_field_p = const_str;
str = u.mutable_field_p;
现在您可以使用free(str); 释放内存。
但是请注意,这超出了单词的含义,应仅在严格控制的环境中使用(例如,分配和释放字符串但不希望允许用户修改它们的库),否则当有人提供时,您将最终导致程序崩溃将时间“ STRING”编译为自由函数。
union
当普通演员可以自己改变状态时,为什么在地球上您会毫无意义地使用这种丑陋的技巧const
?