cwindowslzw

Element disapears while calling a function - LZW Compression


I made some research but nothing was really concerning my problem...

I'm actually trying to code LZW compression for school, and I need a function to check if an element is in my dictionnary.

However, when I'm calling this function, it tries to access to the 64th element in my dictionnary, but it has desapeared !! I checked it before the function calling, it was here !! And the worse is that I can call this element in the previous callings of the function.

Could you help me please ?

The function :

int is_in_dictionnary(dico * p_pRoot, char * p_string){
    int i = 0, j = 0;
    char a[1024] = { 0 }, b[1024] = { 0 };

    //strcpy(b, p_pRoot->m_dico[64].m_info);


    for (i = 0; i < p_pRoot->m_index; i++){
        printf("dico %s\n", p_pRoot->m_dico[i].m_info);

        strcpy(a, p_string);
        strcpy(b, p_pRoot->m_dico[i].m_info);

        j = strcmp(a, b);

        if (j == 0)
            return i;
    }
    return -1;
}

The console, we are herer abble to see that the function previously called the 64th element "@", whithout any problem

The error on visual studio


Some people Asked me to add the code part where it's not functionning :

void lzw_compress(dico *p_pRoot, char * path)
{
    FILE *pFile = NULL, *pCompFile = NULL;

    int len_c = 0, size_tamp = 0, i = 0, masked_tamp = 0, tamp_to_write = 0, index_tamp = 0, a;
    unsigned char char_tamp = 0, cAndTamp[1024] = { 0 }, tampon[1024] = { 0 }, c = '\0', temp[2] = { 0 };

    char test[128] = { 0 };

    pFile = fopen(path, "r+");
    if (!pFile)
    {
        printf("problem while opening file to compress");
        return;
    }


    size_t len = strlen(path);      //creation of the output file name : paht+ ".lzw"
    unsigned char *compress_name = malloc(len + 4 + 1);
    strcpy(compress_name, path);
    compress_name[len] = '.';
    compress_name[len + 1] = 'l';
    compress_name[len + 2] = 'z';
    compress_name[len + 3] = 'h';
    compress_name[len + 4] = '\0';

    pCompFile = fopen(compress_name, "w");  //creation of the output file

    free(compress_name);

    while (1)
    {
        if (feof(pFile))
            break;

        c = freadByte(pFile);


        for (i = 0; i < 1024; i++)
            cAndTamp[i] = 0;

        temp[0] = c;

        strcat(cAndTamp, tampon);
        strcat(cAndTamp, temp);

        strcpy(test, p_pRoot->m_dico[64].m_info);

        a = 0;


        if (is_in_dictionnary(p_pRoot, cAndTamp) > -1)
        {
            strcpy(tampon, cAndTamp);
            a = 0;
        }

        else
        {
            if (is_in_dictionnary(p_pRoot, tampon) < 256)   //write the character in the file
            {
                char_tamp = tampon[0];
                fwrite(&char_tamp, sizeof(char), 1, pCompFile);
                a = 0;
            }

            else
            {

                a = 0;

                index_tamp = is_in_dictionnary(p_pRoot, tampon);

                a = 0;

                for (i = 0; i < p_pRoot->m_size; i++)
                {
                    mask = 1 << i;
                    masked_tamp = index_tamp & mask;
                    tamp_to_write = masked_tamp >> i;

                    fwriteBit(tamp_to_write, pCompFile);
                    flush(pCompFile);

                }
            }

            strcpy(test, p_pRoot->m_dico[64].m_info);   //HERE IT'S OK

            add_dictionnary(p_pRoot, cAndTamp, size_tamp + 1);  //add the string tamp + read byte in the dictionnay

            strcpy(test, p_pRoot->m_dico[64].m_info);       //HERE IT IS NOT OK

            strcpy(tampon, temp);
        }

        strcpy(test, p_pRoot->m_dico[64].m_info);
        size_tamp = is_in_dictionnary(p_pRoot, tampon);
    }

    if (tampon < 256)   //write the character in the file
    {
        char_tamp = (char)tampon;
        fwrite(&char_tamp, sizeof(char), 1, pCompFile);
    }

    else
    {
        index_tamp = is_in_dictionnary(p_pRoot, tampon);
        for (i = 0; i < p_pRoot->m_size; i++)
        {
            mask = 1 << i;
            masked_tamp = index_tamp & mask;
            tamp_to_write = masked_tamp >> i;

            fwriteBit(tamp_to_write, pCompFile);
            flush(pCompFile);
        }
    }


    fclose(pFile);
    fclose(pCompFile);

}

The fucnction that where I think there is a problem

void add_dictionnary(dico * p_pRoot, char * p_string, int p_stringSize)
{
    p_pRoot->m_index++;

    if (p_pRoot->m_index ==  pow(2, p_pRoot->m_size))
        realloc_dictionnary(p_pRoot);


    p_pRoot->m_dico[p_pRoot->m_index].m_info = (char*)calloc(p_stringSize, sizeof(char));
    strcpy(p_pRoot->m_dico[p_pRoot->m_index].m_info, p_string);

}

Another thank you guys !


Solution

  • I showed again the program to my teacher and he found the problem ! The problem is that i never use malloc and rarely use realloc so here was the problem :

    void realloc_dictionnary(dico * p_pRoot)
    {
        int real = p_pRoot->m_size + 1;
        int size = pow(2, real);
    
        printf("index %d, previous pow %d, new power %d, size %d\n", p_pRoot->m_index, p_pRoot->m_size, real, size);
    
        p_pRoot->m_dico = (code*) realloc(p_pRoot->m_dico, size);
    
        p_pRoot->m_size = real;
    }
    

    size in a number of bits, ... So the correction is : size * sizeof(code)!

    void realloc_dictionnary(dico * p_pRoot)
    {
        int real = p_pRoot->m_size + 1;
        int size = pow(2, real);
    
        printf("index %d, previous pow %d, new power %d, size %d\n", p_pRoot->m_index, p_pRoot->m_size, real, size);
    
        p_pRoot->m_dico = (code*) realloc(p_pRoot->m_dico, size * sizeof(code));
    
        p_pRoot->m_size = real;
    }
    

    I would like to first of all say sorry because of this so little errror and also a big thanks for your great patience !