どうすれば を解放できconst char*
ますか? を使用して新しいメモリを割り当てましmalloc
たが、それを解放しようとすると、常に「互換性のないポインタ型」というエラーが表示されます
これを引き起こすコードは次のようなものです。
char* name="Arnold";
const char* str=(const char*)malloc(strlen(name)+1);
free(str); // error here
何人かが正解を投稿しているのになぜか削除し続けています。非 const ポインターにキャストする必要があります。ではなくfree
をとります:void*
const void*
free((char*)str);
コードが逆になっています。
これ:
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()
実際に変更できるため、期待どおりに動作します。
const へのポインターを malloc しても意味がありません。その内容を (醜いハックなしでは) 変更できないからです。
ただし、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
$
どのコンパイラを使用していますか?
を解放したい場合があります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ポインタを受け取る関数は、渡されたメモリを解放する責任を負わないようにする必要があります。
いくつかの回答は、単純に にキャストすることを提案していchar*
ます。しかし、上で el.pescado が書いたように、
const
non- へのキャストconst
は、コードの匂いの症状です。
-Wcast-qual
gccなど、これを防ぐコンパイラ警告があり、これは非常に便利です。ポインターを解放する有効なケースが本当にある場合(多くの人がここに書いたことに反して、nlstd が指摘したように有効なケースがあります)、次のようにその目的のためにマクロを定義できます。const
#define free_const(x) free((void*)(long)(x))
これは、少なくとも gcc では機能します。ダブルキャストにより、ロジック-Wcast-qual
はこれを「const のキャストアウェイ」として検出しません。言うまでもなく、このマクロは注意して使用する必要があります。実際には、同じ関数で割り当てられたポインターに対してのみ使用する必要があります。
私は間違っているかもしれませんが、問題はにあると思いますconst
。次のようにポインタを非 const にキャストします。
free((char *) p);
あなたconst
が言うから:このポインターが指すデータを変更しないでください。
ポインタを非 const にキャストしても、free will の結果は実装に依存すると思います。通常 const は、変更したくない変数用に設計されています!!
const char *
ですので解放できませんconst
。から受け取ったポインターをmalloc
非 const ポインター変数に格納して、 に渡すことができるようにしますfree
。char *
引数を取る関数に引数を渡すことができconst char *
ますが、その反対が常に当てはまるとは限りません。
void foo (const char *x);
char *ptr = malloc (...);
foo (ptr);
free (ptr);