C语言 无法在 C 中释放常量指针

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2819535/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 05:25:34  来源:igfitidea点击:

Unable to free const pointers in C

cconstfree

提问by lego69

How can I free a const char*? I allocated new memory using malloc, and when I'm trying to free it I always receive the error "incompatible pointer type"

我怎样才能释放一个const char*?我使用 分配了新内存malloc,当我尝试释放它时,我总是收到错误“不兼容的指针类型”

The code that causes this is something like:

导致这种情况的代码类似于:

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

free(str); // error here

回答by Michael Mrozek

Several people have posted the right answer, but they keep deleting it for some reason. You need to cast it to a non-const pointer; freetakes a void*, not a const void*:

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

free((char*)str);

回答by Tim Post

Your code is reversed.

你的代码被颠倒了。

This:

这个:

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

Should look like this:

应该是这样的:

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

The conststorage type tells the compiler that you do not intend to modify a block of memory once allocated (dynamically, or statically). Freeing memory is modifying it. Note, you don't need to cast the return value of malloc(), but that's just an aside.

const存储类型告诉编译器,你不打算修改的内存块一次分配(动态,或静态)。释放内存就是修改它。请注意,您不需要强制转换 malloc() 的返回值,但这只是一个问题。

There is little use in dynamically allocating memory (which you are doing, based on the length of name) and telling the compiler you have no intention of using it. Note, usingmeaning writing something to it and then (optionally) freeing it later.

动态分配内存(您正在执行的操作,基于 的长度name)并告诉编译器您无意使用它几乎没有用。请注意,使用意思是向它写入一些东西,然后(可选)稍后释放它。

Casting to a different storage type does not fix the fact that you reversed the storage types to begin with :) It just makes a warning go away, which was trying to tell you something.

转换为不同的存储类型并不能解决您一开始就颠倒存储类型的事实:) 它只是让警告消失,它试图告诉您一些事情。

If the code is reversed (as it should be), free()will work as expected since you can actually modifythe memory that you allocated.

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

回答by Paul R

It makes no sense to malloc a pointer to const, since you will not be able to modify its contents (without ugly hacks).

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

FWIW though, gcc just gives a warning for the following:

不过,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
$ 

What compiler are you using ?

你用的是什么编译器?

回答by nlstd

There are cases you want to free a const*. However you don't want to do it unless you allocate/asign it in the same function. Else you are likely to break things. See the code below for a real world example. I use constin the function declarations to show that I am not changing the content of the arguments. However it is reassignedwith a lowercased duplicate (strdup) that needs to be freed.

有些情况下您想释放const*. 但是,除非您在同一函数中分配/分配它,否则您不想这样做。否则你很可能会破坏东西。有关真实示例,请参阅下面的代码。我const在函数声明中使用以表明我没有更改参数的内容。然而,它被重新分配了一个需要释放的小写副本 (strdup)。

char* tolowerstring(const char *to_lower)
{
    char* workstring = strdup(to_lower);
    for(;workstring != '
#define free_const(x) free((void*)(long)(x))
'; 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)] == '
free((char *) p);
') { free(tail); free( (char*) extension); return 1; } } free(tail); free( (char *) extension); return 0; }

回答by Puppy

There's no purpose in casting a malloc'd pointer to const. Any function that takes a const pointer should not be responsible for freeing the memory that was passed to it.

将 malloc 的指针强制转换为 const 是没有意义的。任何采用 const 指针的函数都不应该负责释放传递给它的内存。

回答by uncleremus

Several answers have suggested simply casting to char*. But as el.pescado wrote above,

几个答案建议简单地强制转换为char*. 但正如 el.pescado 上面写的那样,

casting constto non-constis a symptom of code smell.

强制转换const为 non-const是代码异味的症状。

There are compiler warnings that guard against this, such as -Wcast-qualin gcc, which I find very useful. If you reallyhave a valid case for freeing a constpointer (contrary to what many have written here, there arevalid cases, as pointed out by nlstd), you could define a macro for that purpose like this:

有一些编译器警告可以防止这种情况发生,例如-Wcast-qual在 gcc 中,我发现它非常有用。如果你真的有一个有效的释放const指针的情况(与许多人在这里写的相反,有一些有效的情况,正如 nlstd 所指出的那样),你可以为此目的定义一个宏,如下所示:

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;

This works at least for gcc. The double cast makes the logic -Wcast-qualnot detect this as "casting const away". Needless to say, this macro should be used with care. Actually it should only be used for pointers allocated in the same function.

这至少适用于 gcc。双重转换使逻辑-Wcast-qual无法将其检测为“将 const 丢弃”。不用说,这个宏应该小心使用。实际上它应该只用于在同一函数中分配的指针。

回答by Felix Kling

I could be wrong but I think the problem lies in const. Cast the pointer to non-const like:

我可能是错的,但我认为问题出在const. 将指针转换为非常量,例如:

void foo (const char *x);
char *ptr = malloc (...);
foo (ptr);
free (ptr);

Because with constyou say: Don't change the data this pointer points to.

因为和const你说:不要改变这个指针指向的数据

回答by MMasterSK

If you are talking about pure C and you are in complete control of the memory allocation you can use the following trick to cast (const char *) to (char *) which will not give you any warning in compiler:

如果您在谈论纯 C 并且您完全控制内存分配,则可以使用以下技巧将 (const char *) 强制转换为 (char *),这不会在编译器中给您任何警告:

free(p);
p = NULL;

Now you can use free(str); to free the memory.

现在你可以使用 free(str); 释放内存。

But BEWARE that this is evil beyond words and should be only used in strictly controlled environment (e.g. library which allocates and frees strings, but doesn't want to allow user to modify them) Otherwise you will end up with your program crashing when someone provides compile time "STRING" to your free function.

但请注意,这是无法言喻的邪恶,只能在严格控制的环境中使用(例如,分配和释放字符串的库,但不想允许用户修改它们)否则,当有人提供时,您最终会导致程序崩溃编译时间“字符串”到您的免费​​功能。

回答by el.pescado

You cannot free const char *because it is const. Store pointers received from mallocin non-const pointer variables, so that you can pass them to free. You can pass char *arguments to functions taking const char *arguments but opposite is not always true.

你不能自由,const char *因为它是const。将收到的指针存储malloc在非常量指针变量中,以便您可以将它们传递给free. 您可以将char *参数传递给带const char *参数的函数,但相反的情况并非总是如此。

##代码##

回答by free

I think the real answer is that free should take a constpointer argument and NULLshould be defined as a constpointer. This seems to be a bug in the standards. Freeing a constpointer should be implemented as follows:

我认为真正的答案是 free 应该接受一个const指针参数并且NULL应该被定义为一个const指针。这似乎是标准中的错误。释放const指针应按如下方式实现:

##代码##

I don't see how a compiler could generate incorrect code in this case, the constpointer pis no longer accessible, so it doesn't matter if the object it pointed to is const, valid, whatever else. Its constso there can't be any dirty copies in registers or anywhere else. It is valid to set a constpointer to another value, and the fact that that value is NULLdoesn't matter because the previous value is no longer accessible.

在这种情况下,我看不到编译器如何生成不正确的代码,const指针p不再可访问,因此它指向的对象是否const有效都无关紧要。其const所以不能在寄存器中或其他地方的任何肮脏的副本。将const指针设置为另一个值是有效的,并且该值是否NULL存在的事实无关紧要,因为不再可以访问先前的值。