0
gcc (GCC) 4.7.2
c89

こんにちは、

All error checking removed from snippet - to keep the code short.

文字列を割り当ててコピーしたメモリの解放に問題があります。

私のプログラムは数字をチェックし、数字以外になるまでポインターをインクリメントします。

メモリを解放しようとすると、無効な解放のスタック ダンプが表示されます。

これは、ポインターをインクリメントしたためだと思います。現在、ポインターは文字列の途中を指しています。これは、数字以外が始まるときです。インクリメントしない場合は、解放しても問題ありません。ただし、インクリメントしてから解放しようとすると、スタックダンプが取得されます。

int parse_input(const char *input)
{
    char *cpy_input = calloc(strlen(input) + 1, sizeof(char));
    size_t i = 0;

    apr_cpystrn(cpy_input, input, strlen(input) + 1);



    /* Are we looking for a range of channels */
    for(i = 0; i < strlen(cpy_input); i++) {
        if(isdigit(*cpy_input)) {
        /* Do something here */
            cpy_input++;
        }
    }

    /* Where finished free the memory */
    free(cpy_input); /* Crash here */

    return 0;
}

別のポインターを宣言してアドレスを割り当てることで問題を解決したので、最初の文字を指し、それを解放します。それは正常に動作します。

  char *mem_input = cpy_input;
  free(mem_input);

私の質問は、メモリを解放できるようにするために別のポインターを宣言する必要があるのはなぜですか? これを行う別の方法はありますか?

よろしくお願いします。

4

6 に答える 6

4

元のポインターを保存する必要があります。メモリを解放するときは、元のポインターのみを使用できます。元のポインターを保持する別の変数を作成するだけです。

または、ループを別の関数に入れます。デフォルトでは、変数は値渡し、つまりコピーされるため、関数内でポインターを変更すると、ポインターのコピーのみが変更されます。

それに加えて、あなたのループは少し奇妙に思えます。ゼロから文字列の長さまでのインデックスを使用してループするため、ポインターを変更する代わりにそのインデックスを簡単に使用できます。それか、ループを のようなものに変更しますwhile (*cpy_input != '\0')。2 つの亜種が混在しているのを見たことがありません。

ところで、そのコードにはバグがあります。現在の文字が数字の場合のみ、ポインタを増やします。ただし、最初の文字が数字でない場合、ループは文字列の最後に到達するまでループしますが、ポインターは増加せ、最初の文字を何度も確認します。文字列から先頭の数字を取得したい場合 (もしあれば)、次のようなループを使用できます。

for (; isdigit(*cpy_input); cpy_input++)
{
    /* do something, using `*cpy_input` */
}

またはもちろん

for (int i = 0; i < strlen(cpy_input); i++)
{
    /* do something, using `cpy_input[i]` */
}
于 2013-07-03T05:53:42.747 に答える
1

ループを変更できます

for(i = 0; i < strlen(cpy_input); i++) {
    if(isdigit(cpy_input[i])) {
    /* Do something here */

    }

}

または、後で初期値を取得するためにポインター演算を実行します

于 2013-07-03T05:53:21.183 に答える
1

もちろん、これを行う別の方法がありcpy_inputます。インクリメントした回数だけポインターをデクリメントするだけです。または、文字列の長さ (保存したと仮定) を最終cpy_input値から減算します。そうすれば、元のcpy_input値を復元し、メモリを適切に解放できます。

ここでの要点は単純です:freeから受け取ったのと同じポインター値に渡す必要がありますcalloc。それを回避する方法はありません。したがって、何らかの方法で元のポインター値を取得できる必要があります。それを別のポインターに保存することは、実際にはあなたの状況での最良の解決策です。しかし、他の方法でそれを行う方法を知っている場合は、先に進んで、最も好きなものを使用してください.

于 2013-07-03T05:53:30.920 に答える