2016-11-06 3 views
0

引数リストで指定されたファイルをループし、ファイル内の行をループし、動的に割り当てられた配列に追加する次のプログラムのように、charポインタの配列を "再利用"したいと仮定します。charポインタの再利用

// includes 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <ctype.h> 

// globals 
int progReturn = 0; 
int globalLineCounter = 0; 



////// main 
int main(int argc, char *argv[]) { 
    FILE *fp; 
    int i; 


    // iterate files. first arg is the program name 
    for (i = 1; i < argc; i++) { 
     fp = fopen(argv[i], "r"); 
     if (fp == NULL) { 
      fprintf(stderr, "The file '%s' did not exist.\n", argv[i]); 
      progReturn = 1; 

     } else { 

      // read lines from the file 
      char line[256]; 

      // THE PROBLEM: I'd like to completely clear this array.    
      char **lines = malloc(16 * sizeof(char*)); 

      // iterate lines 
      int fileLineCounter = 0; 
      while (fgets(line, sizeof(line), fp)) { 

       // remove newline 
       strtok(line, "\n"); 

       // add lines to array 
       lines[globalLineCounter] = malloc(256 * sizeof(char)); 
       strcpy(lines[globalLineCounter], line); 
       //printf("%s\n", lines[globalLineCounter]); // tester 

       fileLineCounter++; 
       globalLineCounter++;     
      } 
      // all lines read 
      printf("The file '%s' had %d lines.\n", argv[i], fileLineCounter); 

      // print the array 
      int j=0; 
      for (j=0; j<fileLineCounter; j++) { 
       // PROBLEM: Garbage from the second file when it prints here. 
       printf("%s\n", lines[j]); 
      } 

      // delete lines, delete file 
      memset(lines, 0, sizeof(*lines)); 
      fclose(fp); 
     } 
    } 
    // all files read 

    return progReturn; 
} 

最初のファイルではすべて問題なく動作します。 2番目のファイルで、配列を印刷すると、印刷できない文字と、最初のファイルの行の一部が表示されます。

この問題の原因は何ですか? **linesを完全にクリアしていませんか?


EDIT:例えば入力と出力:

入力ファイルfoo:

This is a test 
of the lineSort program 
in order to 
test its capabilities. 
Lots of whitespace too! 
aaa 

bbb 

     cccccc 



aaa 
ggggg 
hhhhh 
fffff 
eeeee 
ddddd 
ppppp 

入力ファイルバー:

aaaaaaaaaaaaaaaaa 
bbbbbbbbbbbbbbbbb 
zzzzzzzzzzzzzzzzz 
ccccccccccccccccc 
yyyyyyyyyyyyyyyyy 

出力sortLine foo bar用:

The file 'foo' had 20 lines. 





     cccccc 
Lots of whitespace too! 
This is a test 
aaa 
aaa 
bbb 
ddddd 
eeeee 
fffff 
ggggg 
hhhhh 
in order to 
of the lineSort program 
ppppp 
test its capabilities. 
The file 'bar' had 5 lines. 
(x▒▒ 
(x▒▒ 
Lots of whitespace too! 
in order to 
test its capabilities. 
+0

あなたは何も再利用していません。 – melpomene

+0

無関係なニックピック: 'sizeof(char)'は定義上 '1 'なので、それを乗算する必要はありません。 – Arkku

+0

http://stackoverflow.com/help/mcve – melpomene

答えて

1
strcpy(lines[globalLineCounter], line); 

これはあなたの主な問題のように見えます。 globalLineCounterはすべての入力ファイルにわたって増加し続ける。

最初の入力ファイルには10行、2番目のファイルには5行が含まれているとします。次にコードは動的配列の動的配列を作成し、最初のファイルの行を要素0 .. 9に格納してから印刷します。割り当てられたメモリを解放することは決してありません。そのため、ループの最後にすべてがリークします。

2番目のファイルでは、別の動的配列を作成します。 2番目のファイルから5行を要素10 .. 14globalLineCounterを介して)に保存しますが、次に要素(fileLineCounter)を出力します。これらの要素は初期化されておらず、ゴミを含んでいます。

+0

私が言うことができるのは... Doh!それはそれを修正した。どうもありがとうございました。 – chakeda

1
  1. forループの外側にあるchar **lines初期化を移動します。
  2. インデックスカウンタiの名前を変更してください。
  3. lines[i] = malloc(...)を複数のファイルに繰り返し呼び出すと、メモリリークが発生します。 forループ内でfreeを使用するか、またはforループの外側で初期化のこの部分を移動することを考えてください。
+0

それは本当に問題に対処していません。 – melpomene

+0

これはチャットする価値があるかもしれません。このコメント欄に私が言っていることを本当にフィットさせることはできません。 –