0

我慢して。私は8年間cでコーディングしておらず、文字列操作が機能しない理由に完全に困惑しています。私は永遠にループするプログラムを書いています。ループでは、2つのcharポインターを初期化し、それぞれがcharポインター(配列)にテキストを追加する関数に渡されます。関数が完了したら、charポインターを出力し、2つのcharポインターを解放します。ただし、プログラムは7回の反復後に終了し、次のエラーメッセージが表示されます。

*glibcが検出されました* ./test:ダブルフリーまたは破損(ファストトップ):0x0804a168 ***

#include sys/types.h
#include sys/stat.h
#include fcntl.h
#include string.h
#include stdio.h
#include stdlib.h
#include errno.h
#include time.h

char *SEPERATOR = "|";

void getEvent (char* results);
void getTimeStamp(char* timeStamp, int timeStampSize);
void stringAppend(char* str1, char* str2);

int main (int argc, char *argv[])
{
  int i = 0; 
  while(1)
  { 
    i++;
    printf("%i", i);    

    char* events= realloc(NULL, 1); 
    events[0] = '\0';
    getEvent(events);

    char* timestamp= realloc(NULL, 20);
    timestamp[0] = '\0';
    getTimeStamp(timestamp, 20);

    printf("%s", events);
    printf("timestamp: %s\n", timestamp);

    free(events);
    free(timestamp);
  } 
}

void getEvent (char* results)
{
  stringAppend(results, "a111111111111");
  stringAppend(results, "b2222222222222");
}

void getTimeStamp(char* timeStamp, int timeStampSize)
{
  struct tm *ptr;
  time_t lt;
  lt = time(NULL);
  ptr = localtime(&lt);
  int r = strftime(timeStamp, timeStampSize, "%Y-%m-%d %H:%M:%S", ptr);
}

void stringAppend(char* str1, char* str2)
{   
  int arrayLength = strlen(str1) + strlen(str2) + strlen(SEPERATOR) + 1;
  printf("--%i--",arrayLength);

  str1 = realloc(str1, arrayLength);
  if (str1 != NULL)
  {
    strcat(str1, SEPERATOR);
    strcat(str1, str2);
  }
  else
  {
    printf("UNABLE TO ALLOCATE MEMORY\n");
  }
}
4

5 に答える 5

7

関数から値を再割り当てしていますがstr1、値を渡していないため、変更された可能性のあるポインターがリークされ、によって解放された古い値がrealloc再び解放されます。これにより、「ダブル フリー」警告が発生します。

于 2010-07-07T03:33:21.097 に答える
4

問題は、stringAppend がポインターを再割り当てしている間、stringAppend だけがこの事実を認識していることです。元のポインターが更新されるように、stringAppend を変更してポインターへのポインター (char **) を取得する必要があります。

于 2010-07-07T03:34:23.063 に答える
4

stringAppend のこの行:

str1 = realloc(str1, arrayLength);

stringAppend のローカル変数の値を変更します。str1 という名前のこのローカル変数は、再割り当てされたメモリまたは NULL のいずれかを指すようになりました。

一方、getEvent のローカル変数は以前の値を保持し、通常は解放されたメモリを指します。

于 2010-07-07T03:34:50.867 に答える
1

非常に役立つすべてのコメント。もちろん、エラーが発生した理由は完全に理にかなっています。次の変更を加えることで解決しました。

getEvent と stringAppend の両方で、char ポインターを返します。

例えば

char* stringAppend(char* str1, char* str2) 
{    
  int arrayLength = strlen(str1) + strlen(str2) + strlen(SEPERATOR) + 1; 
  printf("--%i--",arrayLength); 

  str1 = realloc(str1, arrayLength); 
  if (str1 != NULL) 
  { 
    strcat(str1, SEPERATOR); 
    strcat(str1, str2); 
  } 
  else 
  { 
    printf("UNABLE TO ALLOCATE MEMORY\n"); 
  } 
  return str1;
} 
于 2010-07-07T04:23:31.133 に答える
0

これはあなたの質問に対する回答ではありません (エラーが指摘されているので、回答は必要ありません) が、あなたのコードについて他にもいくつかコメントがあります。

char* events= realloc(NULL, 1); 
events[0] = '\0';

realloc正常に割り当てられたメモリをテストしません。

char* timestamp= realloc(NULL, 20);
timestamp[0] = '\0';

ここでも同じ問題。この場合、まったく必要ありませんrealloc。これは固定サイズのバッファであるため、次のように使用できます。

char timestamp[20] = "";

そして、これをしないでください:

str1 = realloc(str1, arrayLength);

失敗すると、以前に指してreallocいたメモリが孤立するためです。str1その代わり:

char* temp = realloc(str1, arrayLength);
if (temp != NULL)
{
    str1 = temp;
    ...
}

新しい文字列を返すように変更stringAppendしているため、呼び出し関数で同様のチェックを行う必要があることに注意してください。

また、「separator」は、2 つの E ではなく、2 つの As で綴られます。

于 2010-07-07T06:01:23.240 に答える