0

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 !

maleik
  • 33
  • 1
  • 1
  • 7
  • Please post [mcve]. – Eugene Sh. Feb 07 '19 at 16:28
  • 1
    btw, I see no point in copying the strings to local buffers just for comparing. – Eugene Sh. Feb 07 '19 at 16:29
  • Not enough information here. Looks like the value of `p_pRoot->m_index` might be off. – 500 - Internal Server Error Feb 07 '19 at 16:29
  • Hi Guys, For @EugeneSh. I'm not abble to post this type of example, because the error appears when I call is_in_dictionnatry from the compression function :/ I know that copy the strings is useless, but I was to see if it solve the problem – maleik Feb 07 '19 at 16:46
  • @500-InternalServerError I'm not sure to understand what do you mean by "might be off", sorry. – maleik Feb 07 '19 at 16:49
  • Without [mcve] we won't be able to help you, sorry. The posted code has no visible problem by itself. – Eugene Sh. Feb 07 '19 at 16:49
  • It might be greater than the size of the `m_dico` array, is what I mean, but we can't tell from what you show. – 500 - Internal Server Error Feb 07 '19 at 16:57
  • I'll try to do something :) I now located where the '@' disapears, it's in the function that add a char to my dictionnary – maleik Feb 07 '19 at 17:05
  • @500-InternalServerError Technically, it would be impossible, because the initial size of my dictionnary is 2^8 so 256, and now it's 2^9. – maleik Feb 07 '19 at 17:07
  • Have you solved the issue? If you need further help you can post a link with the full source code or an example of it. In the function you posted there is nothing wrong, probably the issue is in other functions or in the way you create your dictionary. – Lapo Feb 07 '19 at 17:45
  • Hi, I'm sorry, but I haven't found any issue for this moment .. But I've located where it fails, it after that I call the function to add an element to the dictionnary. I'll looking at that tomorrow, I'll give you new ! – maleik Feb 08 '19 at 20:07
  • @Lapo , could you tell me where I can post a link to give you an access to my source code ? – maleik Feb 09 '19 at 17:57
  • @maleik You can post it here in the comments if there aren't any problems (for example if it contains personal data or for any other reason). Unluckily I think that in Stackoverflow there aren't direct messages. By the way, if it is a simple and readable source code I suggest you to post it here, so that more people can help you, and not only me (since I'm not very experienced and I'm not completely sure I can help you to spot the issue). If you can post a shorter [example](https://stackoverflow.com/help/mcve), as other users suggested, is even better. Good evening! – Lapo Feb 09 '19 at 18:23
  • Hi @maleik I still have some questions: what is `realloc_dictionnary(*dico)`? I guess `dico` is a type you defined by using typedef on a struct: how is that struct defined? And how do you initialize your `dico` _object_? Last, `tampon` is a string (an array of 1024 `char` specifically), so what is the meaning of `if(tampon<256)`? Moreover I think the error you get is telling you that you are trying to access an element outside the array, this means that the condition of the loop `im_index` is probably wrong, or you initialized `m_index` in the wrong way. Hope to help, good afternoon! – Lapo Feb 10 '19 at 15:12
  • Yes, dico is a type for dictionnary, that contains the size of the dictionnary, the index in this dictionnary, and a tab of code, code is a struct with a string and an int that contains the string size I initialize my dictionnary by filling the ASCII table for tampon < 256, it's to just write directly the ascii character, – maleik Feb 11 '19 at 11:56
  • My problem is that an element disapears in my dictionnary : I can access the 64th element of my dico (so, the 64 char of the ascii table, '@'), by after havec called the function add_dictionnary, I'm unable to access this 64th element ! :/ – maleik Feb 11 '19 at 11:58
  • @maleik Ok, but you didn't post the `realloc_dictionnary` funcion, probably the error is there (judging by its name it is an error prone function). It is not easy to debug a program if you only have fragments of it... – Lapo Feb 11 '19 at 20:15
  • @maleik Oh sorry I didn't notice you solved your problem, glad managed to! – Lapo Feb 11 '19 at 20:16
  • Thanks you verry much @Lapo for you patience !!! and don't worry ;) Thanks also to 500 Internal erro ! and Eugene Sh – maleik Feb 11 '19 at 20:37
  • @maleik no problem, you are welcome! – Lapo Feb 11 '19 at 22:48

1 Answers1

0

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 !

maleik
  • 33
  • 1
  • 1
  • 7