2017-06-13 5 views
0

私の最初のプロジェクトをC言語で書こうとしていて、メモリリークに問題があります。私は間違いを見つけることができませんが、私はdo-whileループで何か問題があると考えます。プログラムはコンパイルされますが、開こうとするとセグメンテーションフォールトエラーが発生します。私は間違って何をしていますか?Cプログラムでメモリリークが見つかりません

私のプログラムで開いているファイルは、文字列のある.txtです(例:dvorndvl)。

私の目的は:引数でプログラムを開き、argv [1]という名前のファイルを開き、ファイルから文字列を配列に書き込みます。

#include<stdio.h> 
#include<stdlib.h> 
#include<string.h> 
#include"file1.h" 
#include"file2.h" 

void bye(){ 
    puts("See you!"); 
} 

int main(int argc, char *argv[]) { 
    char a[30]; 
    int i, x; 

    printf("-----SOME TEXT-----"); 

    FILE *f; 
    f = fopen(argv[1], "r"); 

    if (f = NULL) { 
     printf("User doesn't exist.\n"); 
     exit(1); 
    } 
    else{ 
     do{ 
      a[i] = getc(f); 
      i++; 
     } while(a[i]!=EOF); 

     char b[30]; 
     printf("Password? "); 
     scanf("%c", b); 

     if(strcmp(a,b) == 0){ 
      printf("\nHi, %s!\n", argv[1]); 
      printf("What do you want to do?"); 
      printf("1. Turn the devices on/off. \n"); 
      printf("2. Change my password. \n"); 
      printf("3. -EXIT-\n"); 

      switch(x) { 
       case 1: 
        devices(); break; //in file1 
       case 2: 
        encrypt(argv[1]); break;//in file2 
       case 3: 
        atexit(bye); break; 
      } 
     } 
     else 
      printf("Password is incorrect\n"); 
    } 
    fclose(f); 
    return 0; 
} 
+1

あなたは現在どのような出力を見ていますか?これが役立つかどうかわかりませんが、おそらくi = 0を初期化します。 – user2309843

+0

デバッガを使用しようとしましたか? – Stargateur

+2

'fgets'を使って' b'を読み込みます。char配列ではなく、charです。 – SHG

答えて

2

アドバイスにgetcから切り替えます。

実際の問題は、コードを間違ってコンパイルしている可能性があり、おそらく学習に悪いリソースを使用していることに起因します。

あなたはgccを使用していて、ターゲットファイルを引数として渡していると思われます。

代わりに、あなたはこのように、-Wallおよびおそらく他のフラグを渡す必要があります。

$ gcc -Wall -Wextra crap.c 
crap.c: In function ‘main’: 
crap.c:18:5: warning: suggest parentheses around assignment used as truth value [-Wparentheses] 
    if (f = NULL) { 
    ^~ 

を使用すると、コンパイラが意図しない割り当て問題はないスポット見ることができるように、あなたはそれを聞いています。それはまた、上記のフラグで尋ねて知っている他の多くの問題を見つけることができます。

また、2つの変数が有効な場合、比較を元に戻すことはどのように役立ちますか。もしif(foo = bar)からif(bar = foo)があなたを助けないなら、if(foo = bar)を切り替える。一方、問題についての警告をコンパイラーに求めて、ケースをキャッチします。

異なるコンパイラを使用している場合は、ほとんどの場合、警告を有効にする方法があります。議論のために、基本的な分析ができないものがあれば、使用をやめてください。 もし(NULL == f)が最も一般的に使用されているスタイルに反するものであり、上で述べたように何かを助けるものではないので、私はあなたにしないことを強くお勧めします。

このコードは、コンパイラが簡単に見つけられるものを超えて、まだかなりバグがあります。私はあとでそれに注釈をつけることがあります。

1

物事のカップルがここで間違っている:あなたがNULLに対してそれをテストし、NULLをするfにない変更され

if (f = NULL) { 

は、ここに私のコードです。 ==を使用してください。将来的にこの種のエラーを防ぐために、そのように、左側にr値を置く:

NULL == f 

次へ:

char b[30]; 
scanf("%c", b); 

あなたが読むためにscanfを使用しようとしていた場合文字列の場合は、%cではなく、%sの書式指定子を使用する必要があります。これは1文字です。私はscanfを全く使わないだろう。代わりにfgetsを使用してください。より安全です。

+0

ファイルの終わりを 'feof'で調べる方が良いですし、bの終わりに0を入れる方が良いです。' b [i] = 0' –

+0

ありがとうございます。その「==」事はとてもシンプルでしたが、私はそれに気付かなかったのです。また、私はscanfを削除し、私のコードにfgetsを入れました。もう一度、ありがとう! :) – Exaequet

+0

@Exaequetあなたは大歓迎です。私の答えがあなたの問題を解決したことを発見した場合は、投票矢印の近くにあるチェックマークをクリックしてそれを受け入れることができます! –

1

私は、「F」はNULLであるかどうかをチェックしません。私は* fにハンドラが問題であると思い、あなたにだけコメント:( が、 を与えるために50の評判を持っていないが、あなたは、Fアサインされています。NULLに

if (f=NULL) { 
    printf("User doesn't exist.\n"); 
    exit(1); 

は次のようになります。

if (f==NULL) { 
     printf("User doesn't exist.\n"); 
     exit(1); 

良い練習はNULLが等しいFであれば、常にチェックすることです:

if (NULL == f) { 
     printf("User doesn't exist.\n"); 
     exit(1); 
あなたも i++ でそれを上げる傾けるように、値を持っているdoesntの最初

int i, x;iため、その場合の

入力を間違えた場合は、プログラムがコンパイルされません:)

+0

ありがとうございます!私はこの問題を解決するために約1時間を費やしました。そして、それはとても簡単でした。私は今、実際には恥じています。良い一日をありがとうアドバイスをありがとう:) – Exaequet

2

を数またはマイナーエラーがここにあります if (f = NULL) {if (f == NULL) {

char a[30];getcに変更する必要がありますが、一時文字列とmallocを使用する必要があり、かなり危険です配列は、(NULLは== f)は無関係と悪いの両方で、あなたのニーズに合うと比較を逆にして持っているfgetc

関連する問題