2012-04-12 12 views
5

私はCにはとても新しく、次のコードで何が問題なのか分からないようです。アドレス0x0はスタックされていない、mallocされていない、または(最近)free'd

int main() { 
    char filen[] = "file.txt"; 
    FILE *file = fopen (filen, "r"); 
    if (file != NULL) 
    { 
     char line [ 128 ]; 
     while (fgets (line, sizeof line, file) != NULL) /* read a line */ 
     { 
      int i; 
      char *result; 
      for(i=0; i< NUM;i++) 
      { 
       char *rep; 
       rep = (char *) malloc (sizeof(mychars[i][0])); 
       strcpy(rep, mychars[i][0]); 
       char *with; 
       with = (char *) malloc (sizeof(mychars[i][1])); 
       strcpy(with, cgichars[i][1]); 
       result = (char *) malloc (sizeof(char) * 128); 
       result = str_replace(line, rep, with); 
      } 


      fputs(result, stdout); 
     } 
    } 
    fclose (file); 


    return 0; 
} 

Valgrindのは、私は、このエラーを与えている:

==4266== Invalid read of size 1 
==4266== at 0x4C286D2: __GI_strlen (mc_replace_strmem.c:284) 
==4266== by 0x5118A8D: fputs (iofputs.c:37) 
==4266== by 0x400A0F: main (repl.c:35) 
==4266== Address 0x0 is not stack'd, malloc'd or (recently) free'd 

repl.cは、このコードの端に向かってfputsで始まる行に対応しています。また

、mycharsは次のようになり、二次元配列である:

char *mychars[NUM][2] = { 
    "a", "97", 
    "b", "98", 
    .... 

誰かがこの問題を解決する方法を教えていただけますか?また、私の現在のコード(特にmalloc)をどのように改善しなければならないかについての指針は、非常に高く評価されます。

編集:コードstr_replace

char *str_replace(char *str, char *orig, char *rep) { 
    char buffer[4096]; 
    char *p; 

    if(!(p = strstr(str, orig))) 
    return NULL; 

    strncpy(buffer, str, p-str); 
    buffer[p-str] = '\0'; 
    sprintf(buffer+(p-str), "%s%s", rep, p+strlen(orig)); 

    return buffer; 

} 

EDIT str_replaceのための2新しいコード、およびメイン

のためのテスト目的のために、私はここで見つかったものと私のstr_replaceメソッドを置き換えました:

What is the function to replace string in C?

A

int main() { 
    static const char filen[] = "file.txt"; 
    FILE *file = fopen (filen, "r"); 
    if (file != NULL) 
    { 
     char line [ 128 ]; 
     while (fgets (line, sizeof line, file) != NULL) /* read a line */ 
     { 
      int i; 
      char *result; 
      for(i=0; i< NUM;i++) 
      { 
       char *rep; 
       rep = (char *) malloc (sizeof(mychars[i][0])); 
       strcpy(rep, mychars[i][0]); 
       char *with; 
       with = (char *) malloc (sizeof(mychars[i][1])); 
       strcpy(with, mychars[i][1]); 
       result = str_replace(line, rep, with); 
      } 


      fputs(result, stdout); 
     } 
    } 
    fclose (file); 


    return 0; 
} 

しかし、私はまだ

==6730== Invalid read of size 1 
==6730== at 0x4C286D2: __GI_strlen (mc_replace_strmem.c:284) 
==6730== by 0x5118A8D: fputs (iofputs.c:37) 
==6730== by 0x400995: main (repl.c:29) 
==6730== Address 0x0 is not stack'd, malloc'd or (recently) free'd 

を取得していますおそらく、この最もイライラする部分は、これらの不正な読み取りエラーが何であるかを知られていない:ndは私のメインが若干変更されています。

 int i; 
     char* result; 
     result = &line[0]; 
     for(i=0; i< NUM_CGICHARS;i++) 
     { 
      char *rep; 
      rep = (char *) malloc (sizeof(char)); 
      strcpy(rep, cgichars[i][1]); 
      char *with; 
      with = (char *) malloc (sizeof(char)*3); 
      strcpy(with, cgichars[i][0]); 
      result = str_replace(result, rep, with); 
      fputs(result, stdout); 
      free(rep); 
      free(with); 
     } 

そして今、私は、出力を得るために始めている:私のようなforループの中央にコードを更新しました

EDIT 3 !しかし、わずか2回の反復の後、私はvalgrindのは、私にこのの全体の束を与えることで、セグメンテーションフォールトを取得:

==9130== Invalid read of size 1 
==9130== at 0x4C286D2: __GI_strlen (mc_replace_strmem.c:284) 
==9130== by 0x5118A8D: fputs (iofputs.c:37) 
==9130== by 0x4009DF: main (teststep1.c:27) 
==9130== Address 0x0 is not stack'd, malloc'd or (recently) free'd 

答えて

5

。その関数はおそらく0を返しますので、fputsは失敗します。

ところで、mallocの返品を投函しないでください。これは余分なものであり、プロトタイプを含めるのを忘れてしまった可能性があります。

編集:str_replaceの機能は、メモリの処理が完全に間違っています。ポインターをローカル変数に戻さないでください。関数を残した後は、スペースは無効です。

+0

ジェンスズ、ありがとう、しかし、私はまだこれを修正する方法を考えていない。コードはstr_replaceの上に – varatis

+0

@varatis、 'str_replace'のために私の編集を参照してください。あなたのプログラムのロジックについては、あなたが達成したいことを理解するのは難しいです。なぜ、あなたが消去したループの中に何かを割り当てているのですか?また、 'fputs'で最後に割り当てられた値を使うのはどこですか? –

+0

私は行ごとにファイルを読み込もうとしていますが、行ごとに、その行の特定の文字をmycharsで指定された文字列に置き換えます。 – varatis

0

NUMが0の場合、resultが初期化されていないと偶然0かもしれません。

malloc()への呼び出し結果を確認していないため、エラーが表示されてNULLポインタに書き込もうとしている可能性があります。

mycharsはどこですか?あなたが最初にすぐstr_replaceのリターンでそれを上書きした後、あなたが緩んでresultのためのスペースを割り当てるこの2行

  result = (char *) malloc (sizeof(char) * 128); 
      result = str_replace(line, rep, with); 

+0

これらはどちらもインポートされた "mychars.h"ファイルで宣言されています。しかし、私はstr_replaceをインクルードするとき以外はこれが動作することにも気付きました...私は先に進んでそのコードを追加しようとしています – varatis

+0

メモリオーバーコミットを実装するオペレーティングシステムでは、 'NULL 'を返す' malloc'は、 。 – dreamlax

+0

@dreamlax:wtf !? – James

0

あなたはmycharsが宣言されている方法を示していないが、この行:それはおそらく唯一の1つのバイトを割り当てよう

rep = (char *) malloc (sizeof(mychars[i][0])) 

が見えます。また、たくさんのメモリを割り当てて、決して解放することはありません。そして、ここで:

result = (char *) malloc (sizeof(char) * 128); 
result = str_replace(line, rep, with); 

あなたはmallocを使用してメモリを割り当てた後、完全にそれの上に別の関数の戻り値を割り当てることによって、そのメモリへのポインタを捨てます。

+0

dreamlax、もう一度、おかげであなたの助けを束縛するが、これを修正/変更するには? – varatis

関連する問題