用于lzw压缩的可变长度字符串数组

时间:2013-02-18 16:27:00

标签: c string compression lzw

这里是功能本身。我在那里有一个段错误,因为显然我无法将字符串分配给数组中的该值。 clang / gcc都给了我一个警告。 Clang's更好一点,“期待char charding 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:修复了很多东西,让它看起来更好。数组比较功能仍然无效(出于某种奇怪的原因)。

1 个答案:

答案 0 :(得分: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_size为1.因此,您将不确定的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*分配给char。我猜不出你想要什么,因为dictionary_size在循环中没有改变。也许您想增加dictionary_size并复制word_character字符串?

    word=character;
    word_size=1;

这里你丢失了最初分配给word的内存的句柄 - 通常称为内存泄漏 - 让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_characterword也没有指向已分配的内存,更多未定义的行为。

    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 wordchar*的大小。你可能打算在这里使用字符串的长度。

    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是未定义的行为。在这种情况下,它甚至是字符串文字。字符串文字是不可修改的,因此这是未定义行为的另一个来源,并且可能因尝试修改字符串文字而崩溃。

    }
    printf("%s",debug);

}