0

ここに関数自体があります。どうやら配列内のその値に文字列を割り当てることができないため、セグメンテーション違反が発生しています。clang/gcc の両方で警告が表示されます。Clangの方が少し優れています。これは、「char *の割り当てを期待する」です。私が試したすべてが機能していないため、その辞書を操作する他の方法はわかりません。また、すべてのヘルパー関数を含めるつもりですが、この関数自体にあると確信しています。

いつものように、私はうまくいく答えに賛成票を投じ、私が個人的に選んだものを受け入れます. とにかく、残りの「ヘルパー」機能を以下に投稿します。

void lzw_compress(char *uncompressed_data,size_t uncompressed_length,char *out){
unsigned long i=0,j=0;
char *character=malloc(1);
char *word=malloc(65535);
char *word_character=malloc(65535);
unsigned long word_size=0;
long *tmp_buffer=malloc(65535);
char *dictionary=malloc(130000);
for(i=0;i<=255;++i){
    dictionary[i]=base_dictionary[i];
}
long index=0;  
unsigned long dictionary_size=256;
for(i=0;i<uncompressed_length;++i){
    character[0]=(unsigned char )uncompressed_data[i];
    //arrcat(word_character,word,word_size,character);
    for(j=0;j<word_size;++j){
        word_character[j]=word[j];
    }
    word_character[j]=*character;
    index=search(dictionary,dictionary_size,word_character);
    if(index!=-1){
        for(j=0;j<(word_size+1);++j){
            word[j]=word_character[j];
        }
        ++word_size;
    }
    else{
        tmp_buffer[j++]=index;
        ++dictionary_size;
        //dictionary[dictionary_size++]=(unsigned long *)word_character;

            dictionary[dictionary_size]=*word_character;

        word=*character;
        word_size=1;
    }
}
if(memcmp(word,"",1)!=0){
    tmp_buffer[j++]=search(dictionary,dictionary_size,word);
}
    char *debug="";
    for(i=0;i<j;++i){
        sprintf(debug,"%s%lu,",debug,tmp_buffer[i]);
    }
    printf("%s",debug);

}

long search(char *table,unsigned long table_length,char
*search_value){
    unsigned long i=0;
    for(i=0;i<table_length;++i){
        if(table[i]==*search_value){
            return i;
        }
    }
    return -1; 
 }

ご覧のとおり、純粋な c で lzw のようなプログラムを実行しようとしています。私は常に-Wall -std=c99 でコンパイルします (プリプロセッサ マクロの悪用に p99.h を使用することがあるため)。しかし、何らかの理由で文字列の配列を機能させることができません。それに似たコードを使用したことは知っています(しかし、明らかにバックアップしていませんでした...)が、とにかくそうです。私はそれを(適切に)どのように行うべきかを理解できません。この問題について誰かの助けをいただければ幸いです。

通常どおり、ここに投稿するコードは、特に明記しない限りパブリック ドメインです。すべてが機能するようになったら、ここに投稿して、探している他の人も機能させることができるようにします。

最後に、このスレッドを読んでくれてありがとう。町に行って戻ってきたら(すでに回答がある場合)、チェック/マークを付けます。しかし、それで落胆しないでください。あなたのソリューションは、私が選んだソリューションよりも優れている可能性があり、それでも賛成票を獲得できるからです。

編集1:コードを以前のものに編集しました(gitによる)。

編集 2: 多くのことを修正し、見栄えを良くしました。それでも、配列比較関数は機能しません(何らかの奇妙な理由で)。

4

1 に答える 1

1

割り当てができたので、そこからエラーとして判断できるポイントがいくつかあります。

for(i=0;i<uncompressed_length;++i){
    character[0]=(unsigned char )uncompressed_data[i];
    //arrcat(word_character,word,word_size,character);
    for(j=0;j<word_size;++j){
        word_character[j]=word[j];
    }

word最初は、を指すメモリは初期化されておらず、 word_size1です。したがって、不確定char word[0]をにコピーしword_character[0]ます。最初に設定するのかword_size = 0、そのコピーループを移動するのか、それとも他の何かをするのかわかりません。

word_character[j]=character;

にを割り当てていchar*ますchar。あなたはおそらくword_character[j] = *character;そこを意味していました(または、同等character[0]のの代わりに)。*character

  dictionary[dictionary_size]=word_character;

再びにを割り当てchar*ますchardictionary_sizeループ内で変更されていないため、ここで何が必要かは推測できません。文字列をインクリメントdictionary_sizeしてコピーしたいのではないでしょうか。word_character

    word=character;
    word_size=1;

ここでは、最初に割り当てられたメモリへのハンドルが失われていますword(一般にメモリリークとして知られています) 。1文字分wordの十分なスペースがあるメモリブロックをポイントします。あなたはおそらく、指さされたキャラクターをコピーするつもりでした、

word[0] = character[0];

そこの?


元のコードの最初の答え:

void lzw_compress(char *uncompressed_data,size_t uncompressed_length,char *out){
unsigned long i=0,j=0;
char *character;
char *word;
char *word_character;
unsigned long word_size=1;
long *tmp_buffer=malloc(65535);
char *dictionary;
for(i=0;i<=255;++i){
    dictionary[i]=base_dictionary[i];
}

dictionary指すメモリを割り当てていません。これは、セグメンテーション違反の確率がゼロではない未定義の動作です。

long index=0;  
unsigned long dictionary_size=256;
for(i=0;i<uncompressed_length;++i){
    character[0]=(unsigned char )uncompressed_data[i];

どちらにもメモリを割り当てていません。これcharacterも未定義の動作です。

    //arrcat(word_character,word,word_size,character);
    for(j=0;j<word_size;++j){
        word_character[j]=word[j];
    }

word_characterまたword、割り当てられたメモリを指さないでください。未定義の動作です。

    word[j]=(unsigned long)character;

にキャストし、char*そのunsigned long値を(割り当てられていない)に割り当てcharます。word[j]有効な記憶だったとしても、ここでの意図は何ですか?

    index=search(dictionary,dictionary_size,word_character);
    if(index!=-1){
        for(j=0;j<(word_size+1);++j){
            word[j]=word_character[j];
        }
        ++word_size;
    }
    else{
        tmp_buffer[j++]=index;
        ++dictionary_size;
        //dictionary[dictionary_size++]=(unsigned long *)word_character;
      for(j=0;j<word_size;++j){
            dictionary[dictionary_size]=word_character;
       }
        word=character;
        word_size=1;
    }
}
if(memcmp(word,"",sizeof word)!=0){

sizeof wordのサイズですchar*。ここでは、おそらく文字列の長さを使用するつもりでした。

    tmp_buffer[j++]=search(dictionary,dictionary_size,word);
}
    char *debug="";
    for(i=0;i<j;++i){
        sprintf(debug,"%s%lu,",debug,tmp_buffer[i]);

sprintfソースと宛先が重複している呼び出しは、未定義の動作です。この場合、それは文字列リテラルですらあります。文字列リテラルは変更できないため、これは未定義動作のもう1つの原因であり、文字列リテラルを変更しようとするとクラッシュする可能性があります。

    }
    printf("%s",debug);

}
于 2013-02-18T16:43:44.020 に答える