2017-01-14 6 views
2

になります。これは私のコードです:./a.out rome turin rome milan venice milan florence印刷コマンドライン引数は、セグメンテーションフォールト

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

int isPresent(char *array[], char *string, int dimension) { 
    for (int i=0; i<dimension; i++) { 
    if (strcmp(array[i], string) != 0) { 
     continue; 
    } else { 
     return 1; 
    } 
    } 
    return 0; 
} 

int main(int argc, char *argv[]) { 
    int dim = 0; 
    char **without_duplicates = malloc(dim * sizeof(char *)); 
    for (int i=1; i<argc; i++) { 
    if (!isPresent(without_duplicates, argv[i], dim)) { 
     realloc(without_duplicates, (dim + 1) * sizeof(char *)); 
     without_duplicates[dim] = malloc((strlen(argv[i]) + 1) * sizeof(char)); 
     strcpy(without_duplicates[dim], argv[i]); 
     printf("%s\n", without_duplicates[dim]); 
     dim++; 
    } else { 
     continue; 
    } 
    } 
    printf("%s\n", "Not duplicated arguments:"); 
    for (int i=0; i<dim; i++) { 
    printf("%s\n", without_duplicates[i]); 
    } 
    return 0; 
} 

私はコードを実行します。 しかし、セグメンテーションフォールトエラーを取得します。

コードをデバッグしようとしましたが、ある時点まで動作します。 たとえば、rometurinrome、コピーmilanを破棄しますが、veniceと他の都市はコピーしません。

一部の都市では、他の都市では使用できません。 プログラムに予期しない動作が発生し、異なる引数を使用して異なるポイントでクラッシュします。

引数の数とその長さがわからないので、重複のない新しい配列を動的に割り当てる必要があります。あなたのコードで

+2

['realloc '](http://en.cppreference.com/w/c/memory/realloc)。正しく使用していません。その戻り値には理由があります。リンクされた参照にはサンプルが含まれますが、戻り値を無視するものではなく、偶然ではありません。 – WhozCraig

+0

['malloc'](http://en.cppreference.com/w/c/memory/malloc)の詳細については、ゼロ以外のポインタを返すかどうかをゼロの量で割り振るかどうかは実装定義です。 –

答えて

5

、あなたがcppreferenceによると、任意の変数

realloc(without_duplicates, (dim + 1) * sizeof(char *)); 

へのreallocの戻り値を代入されていません。

成功し

の先頭へのポインタを返します新しく割り当てられたメモリ。返されるポインタは、free()またはrealloc()で割り付け解除する必要があります。元のポインタptrは無効化され、そのポインタへのアクセスは未定義の動作です(再配置が実行されていても)。

失敗した場合は、NULLポインタを返します。元のポインタptrは有効なままであり、free()またはrealloc()で割り振り解除する必要があります。

char** temp = realloc(without_duplicates, (dim + 1) * sizeof(char *)); 

if(temp != NULL) { 
    without_duplicates = temp 
} 
else { 
    //handle the unsuccessful allocation 
} 

ノートのようなものをやってみてください。同様に、あなたは、メモリの割り当てが成功したかどうかmalloc()をチェックする必要があります。

1

はこれを試してみてください。私はまた、あなたが

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

int isPresent(char *array[], char *string, int dimension) 
{ 
    for (int i=0; i<dimension; i++) 
    { 
    if (strcmp(array[i], string) == 0) 
     return 1; 
    } 

    return 0; 
} 

int main(int argc, char *argv[]) 
{ 
    int dim = 0; 
    char ** without_duplicates = malloc(dim * sizeof(char *)); 

    for (int i=1; i<argc; i++) 
    { 
    if (!isPresent(without_duplicates, argv[i], dim)) 
    { 
     without_duplicates = realloc(without_duplicates, (dim + 1) * sizeof(char *)); 
     without_duplicates[dim] = malloc((strlen(argv[i]) + 1) * sizeof(char)); 

     strcpy(without_duplicates[dim], argv[i]); 
     dim++; 
    } 
    } 

    printf("%s\n", "Not duplicated arguments:"); 

    for (int i=0; i<dim; i++) 
    { 
    printf("%s\n", without_duplicates[i]); 
    } 

    return 0; 
} 

あなたの問題は、単純にrealloc関数のうち、戻り値を取得していなかった、 Cはものではありませんが気にいけない願って、自分自身があなたのコード内でいくつかの役に立たない文を削除することができ1は、いくつかのメモリを再割り当てする場合は、そのアドレスを格納する変数は、新しい割り当てられたメモリの新しいアドレスを知っていなければならない...高レベルのプログラミング言語として考えることができるので、あなたはそれを格納する必要があります。

without_duplicates = realloc(without_duplicates, (dim + 1) * sizeof(char *)); 

これが原因セグメンテーションf ault新しい割り当てられたアドレスを格納する前にプロセスのコンテキスト内に存在しないアドレスにジャンプし、その中にいくつかのデータを格納しようとすると結果がセグメンテーションエラーを引き起こします。

+0

あなたの提案やコードの改善についても、ありがとうございます。 –

+0

mallocが失敗するとどうなりますか? @CherubimあなたはまたNULL ptrを割り当てられ、strcpyにしようとするとセグメンテーションフォールトが発生します...そうですか?このプログラムには他にも多くのことが間違っていますが、私はこの人に正しくコードを書く方法を教えようとはしていません。現在の問題を定期的に修正する方法を教えてください。 – DrPrItay

+1

私はまだ理解しています。失敗した?明らかにあなたのプログラム内のバグを防ぐために、そうですか? reallocが失敗したとしましょう - もう存在しない、または存在しないメモリへのポインタがあります。 mallocが失敗した場合、私は割り当てられていないメモリへのポインタを持っています - それは存在しません、どちらの場合でも大きなバグを引き起こす可能性があります、私はあなたに非常に同意します。私はコードを書く方法を教えようとはしていません、ちょうど彼のバグを修正する:) @ケルビム – DrPrItay