1

次の(例)コードでvalgrindを実行すると、「Invalid free()/ delete / delete []」が報告され、Invalidsが読み取られます。理由がよくわかりません。誰か説明してもらえますか?

編集:あなたの返事をありがとう、それは今とても明白です。

#include <stdio.h>
#include <stdlib.h>
#include <string.h

void vl_dec(char* a) {
  char* str = a;
  while (*(str+1) != '\0') str++;
  while(*str == '0') {
    *str = '9';
    str--;
  }
  (*str)--;

  if (*a == '0') {
    memmove(a, a+1, strlen(a));
    a = (char*)realloc(a, (strlen(a)+1)*sizeof(char));
    if (a == NULL) {
      fprintf(stderr, "Cannot allocate memory\n");
      exit(1);
    }
  }
}

int main(int argc, char* argv[]) {
  char* a = (char*)malloc(6*sizeof(char));
  if (a == NULL) {
    fprintf(stderr, "Cannot allocate memory\n");
    exit(1);
  }
  strcpy(a, "10000");
  vl_dec(a);
  printf("%s\n", a);
  free(a);
  return 0;
}
4

3 に答える 3

3

あなたの functionmainでは、値によって に渡しavl_decいるため、更新されることはありません - の結果は、返さreallocれるときに失われるローカル変数にのみ格納されvl_decます。代わりに、そのアドレスを渡します。

void vl_dec(char ** a) { *a = realloc(...); }

int main()
{
    char * a = malloc(...);
    vl_dec(&a);
    free(a);
}
于 2012-05-06T22:26:01.567 に答える
1

aそのrealloc戻り値の新しい値が古い値と同じであると仮定することはできません。実際には、ポインターが使用されるたびにポインターを更新する必要があります。realloc内部のの戻り値を正しく保存したので、それを知っていると思いますが、 fromvl_decの新しい値を返す必要があることを忘れていました(または、 a をパラメーターとして to に使用して更新します)。avl_decchar**vl_dec

于 2012-05-06T22:27:16.150 に答える
0

vl_decポインタを参照ではなく値で渡すためです。

メイン関数内のポインターには、メインで宣言された元のポインターが引き続き表示されますreallocvl_decその後realloc、ポインターが無効になるため、valgrind が文句を言います。

これを修正する簡単な方法は、書き換えvl_decてポインターを返すようにすることです。そうすれば、次のように呼び出すことができます:

   a = vl_dec(a);

メインで問題は解決しました。

于 2012-05-06T22:27:52.203 に答える