79

どうすれば を解放できconst char*ますか? を使用して新しいメモリを割り当てましmallocたが、それを解放しようとすると、常に「互換性のないポインタ型」というエラーが表示されます

これを引き起こすコードは次のようなものです。

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

free(str); // error here
4

12 に答える 12

102

何人かが正解を投稿しているのになぜか削除し続けています。非 const ポインターにキャストする必要があります。ではなくfreeをとります:void*const void*

free((char*)str);
于 2010-05-12T14:14:48.290 に答える
27

コードが逆になっています。

これ:

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()実際に変更できるため、期待どおりに動作します。

于 2010-05-13T06:13:25.107 に答える
6

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
$ 

どのコンパイラを使用していますか?

于 2010-05-12T14:17:56.297 に答える
4

を解放したい場合があります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;
}
于 2011-04-24T12:42:12.920 に答える
3

mallocされたポインタをconstにキャストすることに目的はありません。constポインタを受け取る関数は、渡されたメモリを解放する責任を負わないようにする必要があります。

于 2010-05-12T15:02:15.513 に答える
2

いくつかの回答は、単純に にキャストすることを提案していchar*ます。しかし、上で el.pescado が書いたように、

constnon- へのキャストconstは、コードの匂いの症状です。

-Wcast-qualgccなど、これを防ぐコンパイラ警告があり、これは非常に便利です。ポインターを解放する有効なケースが本当にある場合(多くの人がここに書いたことに反して、nlstd が指摘したように有効なケースがあります)、次のようにその目的のためにマクロを定義できます。const

#define free_const(x) free((void*)(long)(x))

これは、少なくとも gcc では機能します。ダブルキャストにより、ロジック-Wcast-qualはこれを「const のキャストアウェイ」として検出しません。言うまでもなく、このマクロは注意して使用する必要があります。実際には、同じ関数で割り当てられたポインターに対してのみ使用する必要があります。

于 2018-02-16T14:38:35.117 に答える
1

私は間違っているかもしれませんが、問題はにあると思いますconst。次のようにポインタを非 const にキャストします。

free((char *) p);

あなたconstが言うから:このポインターが指すデータを変更しないでください

于 2010-05-12T14:12:50.457 に答える
-2

ポインタを非 const にキャストしても、free will の結果は実装に依存すると思います。通常 const は、変更したくない変数用に設計されています!!

于 2010-05-12T14:42:02.953 に答える
-2

const char *ですので解放できませんconst。から受け取ったポインターをmalloc非 const ポインター変数に格納して、 に渡すことができるようにしますfreechar *引数を取る関数に引数を渡すことができconst char *ますが、その反対が常に当てはまるとは限りません。

void foo (const char *x);
char *ptr = malloc (...);
foo (ptr);
free (ptr);
于 2010-05-12T14:12:44.923 に答える