0

セグメンテーション違反が何であるかは知っていますが、その定義を知る必要はありません:)コードのどこから来ているのかを知る必要があるだけです。このプログラムは、単語を入力として取得し、テキスト ファイルから読み取り、別のテキスト ファイルに書き込み、読み取ったファイルと入力からすべての単語を出力することを目的としています。

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

int main(int argc, char*argv[]){
    FILE *read;
    FILE *write;
    char **list=malloc(sizeof(char*));
    char **oldlist=malloc(sizeof(char*));
    char *oldword=malloc(sizeof(char));
    char exit[]="end";
    int a, c, r=0, w=0, n=0, z= 0, y=0, d=0, g=0;

//check arg
for(a=0; a<argc; a++){
    if(strcmp(argv[a], "-r")==0){
        r =1;
        read=fopen("read.txt", "r");
    }
    else if(strcmp(argv[a], "-w")==0){
        w =1;
        write=fopen("write.txt", "w");
    }   
}
if(r==0 && w==0){
    printf("Error: Invalid Command.\n");
}
printf("Read = %d | Write = %d\n", r, w);

//getwords
printf("Enter your words: ");
while(1){
char *word=malloc(sizeof(char));
list=realloc(list, sizeof(char*)*(z+10));
word=realloc(word, sizeof(char)*(z+10));
scanf("%s", word);
              if (strcmp(word,exit)==0){
        break;
              }
              else{
                *(list+z) = word;
            z++;
          }
}   

//read
if (r==1){
    do{
        while(1){
            *(oldword+d)=fgetc(read);
            d++;
        }
    }while(feof(read) != 0);            
}
*(oldword+(d-1))="\0";

printf("Your words are:\n");
            puts(oldword);
    for(c=0; c<n; c++){
            puts(*(list+c));
    }

    //write
    if (w ==1){
        if(w==1){
            fputs(*(oldlist+c),write);
        }
    for(c=0; c<n; c++){
            fputs(*(list+c),write); 
        }
    }
    //end
    free(list);
    fclose(read);
    fclose(write);          
    return 0;

}
4

2 に答える 2

3

ワードに1バイトを割り当てます。

char *word=malloc(sizeof(char));

次に、文字列を読み込みます。これはバッファオーバーフローであり、大きな不幸につながります(そして、Stack Overflowでこのような質問をします)。具体的には、長い単語を読み取ると、「ヒープ」(malloc()et alによって制御されるデータスペース)の制御情報を踏みにじり、使用可能なスペースと使用できないスペースを判別するために使用されるデータをスクランブルします。「長い単語」を構成するものは、システムによって異なります。技術的には、空の文字列(端末のみ'\0')以外の文字列は長すぎますが、単語が7バイト以下の場合は、青い殺人を回避できる可能性があります。


しかし、reallocはメモリの問題を処理するべきではありませんか?文字列入力を無制限にしようとしています。

うーん...ビジネスを行う方法としては少し奇妙ですが、実際に使用する前に、いくつかの問題を回避できますrealloc()word

word具体的には、ループの最初のときにのメモリ割り当てをオーバーフローする前に、最大9文字まで読み取ることができます。ただし、これは「無制限」にすることからは遠い道のりであり、無制限にすることは簡単ではありません。1つの問題は、%s空白文字でスキャンを停止することです。全体として、それはあなたに有利に働きます。もう1つは、z入力した文字列の数として、また入力できる文字列の長さとして使用しているように見えることです。listリストが10エントリを超えた場合、再割り当ては行われません。

それでもさまざまな問題が発生する可能性があります。たとえば、oldwordの処理では、余分なrealloc()は実行されません。1バイトを割り当てるだけです。次に、完全に無制限の無限ループがあります(入力された場合)。このループは災害です:

    while(1){
        *(oldword+d)=fgetc(read);
        d++;
    }
于 2013-03-16T02:39:53.150 に答える
2

デバッグをオンにしてコンパイルし(gフラグ)、valgrindで実行すると、セグメンテーション違反の理由がかなりわかりやすくなります。

于 2013-03-16T02:39:15.293 に答える