0

THIS PROBLEM IS SOLVED, AFTER THE PROBLEM WILL BE THE SOLUTION

in first step I want to apologize for my English level and my level of programming in c

I have a function (get_frecuency_representation) that receive a list of numbers, I create a structure to save the the number and there frequency, the problem is the next, when I return the array I can't access to the memory space.

Frec.c

#include<stdio.h>
#include<stdlib.h>
#include"Frec.h"

Frecuency *get_frecuency_representation(void *frec){
    // This variable will contain the size of a list of poiters pointing to a struct
    int size=0;

    // We create two pointer to walk trhougth the list of numbers and count how many times the number is repeated
    int *pointer=(int*)frec;
    int *pointer2=(int*)frec;

    // We save the start position, that will be useful in a while
    int *pointer_start=pointer;

    // We calculate the size of the list
    while(*pointer!=0){
        size++;
        pointer++;
    }

    // We reset the pointer
    pointer=pointer_start;

    // We create a new list of pointers to structs
    Frecuency *frecuency_list[size];

    // We create a counter to save the position of the arrays
    int counter=0;

    // And we start to calculate the frecuency of each number
    while(*pointer!=0){

        // First we create an structure for each number
        Frecuency *frecuency=malloc(sizeof(frecuency));

        // We assign the number to the structure
        frecuency->number=*pointer;

        // And set the frecuency to 0
        frecuency->frecuency=0;

        // We walk through the list again and compare the number, is it's the same, the frecuency is increased
        while(*pointer2!=0){
            if(*pointer==*pointer2){
                frecuency->frecuency++;
            }
            pointer2++;
        }

        // We save the position of memory of the struct in the array
        frecuency_list[counter]=frecuency;
        
        // And prepare the next cycle
        counter++;
        pointer++;
        pointer2=pointer_start;
    }

    // We reset the pointer
    pointer=pointer_start;

    // We change the frecuency to the next way, the number with the highest frecuency will have the number one, the next with the number two and so on
    int list[size];
    int list_frecuency[size];

    for(int i=0; i<size; i++){
        list[i]=frecuency_list[i]->frecuency;
    }

    // This for will sort the list of frecuencies
    for(int i=0; i<size; i++){
        for(int j=0; j<size; j++){
            if(list[i]>list[j]){
                int aux=list[i];
                list[i]=list[j];
                list[j]=aux;
            }
        }
    }

    // Here we walk througth the ordened list and assign to each number a place
    int visited_numbers[size];

    // We fill visited_numbers and list_frequency with 0
    for(int i=0;i<size;i++){
        visited_numbers[i]=0;
        list_frecuency[i]=0;
    }

    // We reset the counter
    counter=1;
    
    // We start to walk througth the ordened list for change the frequency of the next way if It's the max number we assign 1, then with the next diferent value assign 2, and continue
    for(int i=0; i<size; i++){

        // We look if the number is equal to 0
        if(visited_numbers[i]==0){

            // If it is, look if i>0 in this case, we can look the predecessor of the number to compare
            if(i>0){;

                // If the predecessor is equal to the value in list (It's repited) we set the counter value in list_frequency
                if(visited_numbers[counter-1]==list[i]){
                    list_frecuency[i]=counter;
                }
                
                // If the numbers are not equal, we update the counter with the next value, and set the new information
                else{
                    counter++;
                    visited_numbers[counter-1]=list[i];
                    list_frecuency[i]=counter;
                }
            }
            
            // If it is'nt we se the information in the position 0
            else{
                visited_numbers[counter-1]=list[i];
                list_frecuency[counter-1]=counter;
            }
        }
    }

    // Now we will assign the updated frequency to the numbers
    for(int i=0; i<size; i++){
        for(int j=0; j<size; j++){

            // If the number of the frequency is equal to the list in this point we assign to there the equivalent in frecuency
            if(frecuency_list[i]->frecuency==list[j]){

                // We assign the equivalent
                frecuency_list[i]->frecuency=list_frecuency[j];

                // How we found the number we break the cycle
                break;
            }
        }
    }

    return frecuency_list;
}

Frec* comprimir_en_frec(int n, int* grupo){
    Frec *frec = malloc(sizeof(Frec));
    int bits=bits_frec(grupo);

    char array[bits+1];
    frec->bits=&array[0];
    
    int size=0;

    // We create two pointer to walk trhougth the list of numbers and count how many times the number is repeated
    int *pointer=(int*)grupo;

    // We save the start position, that will be useful in a while
    int *pointer_start=pointer;

    Frecuency *frecuency_list=get_frecuency_representation(grupo);

    // We calculate the size of the list
    while(*pointer!=0){
        size++;
        pointer++;
    }

    // We walk through the list of frecuencies and assign the number to the list of representations
    for(int i=0; i<size; i++){

        // For each number we assign the representation
        for(int j=0; j<frecuency_list[i]->frecuency; j++){
            *frec->bits='1';
            frec->bits++;
        }

        // And we assign the separator
        if(i<size-1){
            *frec->bits='0';
            frec->bits++;
        }
    }

    // We pass to the next value
    frec->bits++;

    // And save this memory position in the struct
    frec->representaciones=frec->bits;

    //Here we delete the repeated numbers for calculate now the length of the secuence
    for(int i=0; i<size; i++){

        // If you watch that like a matrix, we use only the superior triangle, to evit to compare the same number twice
        for(int j=i+1; j<size; j++){

            // If the number is the same, we set the information to 0, i could delete, but i would need to change the size of the array and the position of the pointers
            if(frecuency_list[i]->number==frecuency_list[j]->number){
                frecuency_list[j]->frecuency=0;
                frecuency_list[j]->number=0;
            }
        }
    }

    // Now we add the secuence to remember the numbers
    for(int i=0; i<size; i++){

        // If the number is not 0, we add it to the list
        if(frecuency_list[i]->frecuency!=0){

            // We add the number in unary, then we add the separator to finishing adding the frecuency
            for(int j=0; j<frecuency_list[i]->number; j++){
            *frec->bits='1';
            frec->bits++;
            }
            *frec->bits='0';
            frec->bits++;
            for(int j=0; j<frecuency_list[i]->frecuency; j++){
                *frec->bits='1';
                frec->bits++;
            }
            if(i<size-1){
                *frec->bits='0';
                frec->bits++;
            }
        }
    }

    // We add the end of string
    *frec->bits='\0';

    // We reset the position of the pointer pointin to the start of the array
    frec->bits=&array[0];

    // We free the memory used for the structure
    for(int i=0; i<size; i++){
        free(frecuency_list[i]);
    }

    // We return the structure with the data
    return frec;
}

// This functions gets a list of integers and the size of the list, returns the number of bits needed to represent the list in frecuency
int bits_frec(void *frec){

    // This variable will containt the number of bits necesary for create the representation of the list
    int bits=0;

    // This variable will contain the size of a list of poiters pointing to a struct
    int size=0;

    // This struct wiil be used to save the number of times that a number appears in the list
    typedef struct Frecuency{
        int number;
        int frecuency;
    }Frecuency;

    // We create two pointer to walk trhougth the list of numbers and count how many times the number is repeated
    int *pointer=(int*)frec;
    int *pointer2=(int*)frec;

    // We save the start position, that will be useful in a while
    int *pointer_start=pointer;

    // We calculate the size of the list
    while(*pointer!=0){
        size++;
        pointer++;
    }

    // We reset the pointer
    pointer=pointer_start;

    Frecuency *frecuency_list=get_frecuency_representation(frec);

    // We add the bits of the frecuency of each number
    for(int i=0; i<size; i++){
        bits+=frecuency_list[i]->frecuency;
        if(i!=size-1){
            bits++;
        }
    }

    //Here we delete the repeated numbers for calculate now the length of the secuence
    for(int i=0; i<size; i++){

        // If you watch that like a matrix, we use only the superior triangle, to evit to compare the same number twice
        for(int j=i+1; j<size; j++){

            // If the number is the same, we set the information to 0, i could delete, but i would need to change the size of the array and the position of the pointers
            if(frecuency_list[i]->number==frecuency_list[j]->number){
                frecuency_list[j]->frecuency=0;
                frecuency_list[j]->number=0;
            }
        }
    }

    // Now with the data cleaned, we can calculate the number of bits needed to represent the list
    for(int i=0; i<size; i++){
        if(frecuency_list[i]->number!=0){
            bits+=frecuency_list[i]->number;
            bits++;
            bits+=frecuency_list[i]->frecuency;
            bits++;
        }
    }

    // We remove the extra bit added to the end of the string
    bits--;

    // We free the memory used and return the number of bits
    for(int i=0; i<size; i++){
        free(frecuency_list[i]);
    }

    // We return the number of bits
    return bits;
}

Frec.h

#ifndef FREC_H
#define FREC_H

// We create the struct of the frecuency representation
typedef struct Frec{
    char *bits;
    char *representaciones;
} Frec;

// This struct wiil be used to save the number of times that a number appears in the list
typedef struct Frecuency{
    int number;
    int frecuency;
}Frecuency;

int bits_frec(void *frec);
Frec* comprimir_en_frec(int n, int* grupo);
Frecuency *get_frecuency_representation(void *frec);

#endif

For example when I want to use for(int j=0; j<frecuency_list[i]->frecuency; j++)

I get the next error operator -> or ->* applied to "Frecuency" instead of to a pointer typeC/C++(3364)

SOLUTION

The problem was the next, the variable was local, because was into a function, and the space of memory created is like an array, the solution was change the way that I require the memory, now I use a malloc() to create memory in the heap, and might access to there when it's out the function

This solution comes with some problems, now I have a pointer to structs, so when I use [] operator I have the struct and not a pointer of struct so I changed the -> operator to .

Now I show you the code solved

Frec.c

#include<stdio.h>
#include<stdlib.h>
#include"Frec.h"

// This function gets a list of numbers and will return the number of bits and the representation of the number
Frecuency *get_frecuency_representation(void *frec){

    // This variable will contain the size of a list of poiters pointing to a struct
    int size=0;

    // We create two pointer to walk trhougth the list of numbers and count how many times the number is repeated
    int *pointer=(int*)frec;
    int *pointer2=(int*)frec;

    // We save the start position, that will be useful in a while
    int *pointer_start=pointer;

    // We calculate the size of the list
    while(*pointer!=0){
        size++;
        pointer++;
    }

    // We reset the pointer
    pointer=pointer_start;

    // We create a new list of pointers to structs
    Frecuency *frecuency_list=malloc(sizeof(Frecuency)*size);

    // We create a counter to save the position of the arrays
    int counter=0;

    // And we start to calculate the frecuency of each number
    while(*pointer!=0){

        // First we create an structure for each number
        Frecuency *frecuency=malloc(sizeof(frecuency));

        // We assign the number to the structure
        frecuency->number=*pointer;

        // And set the frecuency to 0
        frecuency->frecuency=0;

        // We walk through the list again and compare the number, is it's the same, the frecuency is increased
        while(*pointer2!=0){
            if(*pointer==*pointer2){
                frecuency->frecuency++;
            }
            pointer2++;
        }

        // We save the position of memory of the struct in the array
        frecuency_list[counter]=*frecuency;
        
        // And prepare the next cycle
        counter++;
        pointer++;
        pointer2=pointer_start;

        free(frecuency);
    }

    // We reset the pointer
    pointer=pointer_start;

    // We change the frecuency to the next way, the number with the highest frecuency will have the number one, the next with the number two and so on
    int list[size];
    int list_frecuency[size];

    for(int i=0; i<size; i++){
        list[i]=frecuency_list[i].frecuency;
    }

    // This for will sort the list of frecuencies
    for(int i=0; i<size; i++){
        for(int j=0; j<size; j++){
            if(list[i]>list[j]){
                int aux=list[i];
                list[i]=list[j];
                list[j]=aux;
            }
        }
    }

    // Here we walk througth the ordened list and assign to each number a place
    int visited_numbers[size];

    // We fill visited_numbers and list_frequency with 0
    for(int i=0;i<size;i++){
        visited_numbers[i]=0;
        list_frecuency[i]=0;
    }

    // We reset the counter
    counter=1;
    
    // We start to walk througth the ordened list for change the frequency of the next way if It's the max number we assign 1, then with the next diferent value assign 2, and continue
    for(int i=0; i<size; i++){

        // We look if the number is equal to 0
        if(visited_numbers[i]==0){

            // If it is, look if i>0 in this case, we can look the predecessor of the number to compare
            if(i>0){;

                // If the predecessor is equal to the value in list (It's repited) we set the counter value in list_frequency
                if(visited_numbers[counter-1]==list[i]){
                    list_frecuency[i]=counter;
                }
                
                // If the numbers are not equal, we update the counter with the next value, and set the new information
                else{
                    counter++;
                    visited_numbers[counter-1]=list[i];
                    list_frecuency[i]=counter;
                }
            }
            
            // If it is'nt we se the information in the position 0
            else{
                visited_numbers[counter-1]=list[i];
                list_frecuency[counter-1]=counter;
            }
        }
    }

    // Now we will assign the updated frequency to the numbers
    for(int i=0; i<size; i++){
        for(int j=0; j<size; j++){

            // If the number of the frequency is equal to the list in this point we assign to there the equivalent in frecuency
            if(frecuency_list[i].frecuency==list[j]){

                // We assign the equivalent
                frecuency_list[i].frecuency=list_frecuency[j];

                // How we found the number we break the cycle
                break;
            }
        }
    }

    return frecuency_list;
}

// This function gets a legth of an array and a list of numbers and will return the number of bits and the representation of the number
Frec* comprimir_en_frec(int n, int* grupo){

    // We assign space in memiry for the structure
    Frec *frec = malloc(sizeof(Frec));

    // We call the function bits_frec to get the number of bits for the representation
    int bits=bits_frec(grupo);

    // We assign space in memory for the representation
    frec->bits=malloc(sizeof(char)*(bits+1));

    // We save the position of the start of the array
    char *pointer_frec_bits=frec->bits;
    
    // We create a variable that will contain the length of the numbers
    int size=n;

    // We create two pointer to walk trhougth the list of numbers and count how many times the number is repeated
    int *pointer=(int*)grupo;

    // We save the start position, that will be useful in a while
    int *pointer_start=pointer;

    // We create a new list of pointers to structs
    Frecuency *frecuency_list;
    frecuency_list=get_frecuency_representation(grupo);


    // We walk through the list of frecuencies and assign the number to the list of representations
    for(int i=0; i<size; i++){

        // For each number we assign the representation
        for(int j=0; j<frecuency_list[i].frecuency; j++){
            *frec->bits='1';
            frec->bits++;
        }

        // And we assign the separator
        if(i<size-1){
            *frec->bits='0';
            frec->bits++;
        }
    }

    // We pass to the next value
    frec->bits++;

    // And save this memory position in the struct
    frec->representaciones=frec->bits;

    //Here we delete the repeated numbers for calculate now the length of the secuence
    for(int i=0; i<size; i++){

        // If you watch that like a matrix, we use only the superior triangle, to evit to compare the same number twice
        for(int j=i+1; j<size; j++){

            // If the number is the same, we set the information to 0, i could delete, but i would need to change the size of the array and the position of the pointers
            if(frecuency_list[i].number==frecuency_list[j].number){
                frecuency_list[j].frecuency=0;
                frecuency_list[j].number=0;
            }
        }
    }

    // Now we add the secuence to remember the numbers
    for(int i=0; i<size; i++){

        // If the number is not 0, we add it to the list
        if(frecuency_list[i].frecuency!=0){

            // We add the number in unary, then we add the separator to finishing adding the frecuency
            for(int j=0; j<frecuency_list[i].number; j++){
            *frec->bits='1';
            frec->bits++;
            }
            *frec->bits='0';
            frec->bits++;
            for(int j=0; j<frecuency_list[i].frecuency; j++){
                *frec->bits='1';
                frec->bits++;
            }
            if(i<size-1){
                *frec->bits='0';
                frec->bits++;
            }
        }
    }

    // We add the end of string
    *frec->bits='\0';

    // We reset the position of the pointer pointin to the start of the array
    frec->bits=pointer_frec_bits;

    // We return the structure with the data
    return frec;
}

// This functions gets a list of integers and the size of the list, returns the number of bits needed to represent the list in frecuency
int bits_frec(void *frec){

    // This variable will containt the number of bits necesary for create the representation of the list
    int bits=0;

    // This variable will contain the size of a list of poiters pointing to a struct
    int size=0;

    // We create two pointer to walk trhougth the list of numbers and count how many times the number is repeated
    int *pointer=(int*)frec;
    int *pointer2=(int*)frec;

    // We save the start position, that will be useful in a while
    int *pointer_start=pointer;

    // We calculate the size of the list
    while(*pointer!=0){
        size++;
        pointer++;
    }

    // We reset the pointer
    pointer=pointer_start;

    // We create a new list of pointers to structs
    Frecuency *frecuency_list;
    frecuency_list=get_frecuency_representation(frec);

    // We add the bits of the frecuency of each number
    for(int i=0; i<size; i++){
        bits+=frecuency_list[i].frecuency;
        if(i!=size-1){
            bits++;
        }
    }

    //Here we delete the repeated numbers for calculate now the length of the secuence
    for(int i=0; i<size; i++){

        // If you watch that like a matrix, we use only the superior triangle, to evit to compare the same number twice
        for(int j=i+1; j<size; j++){

            // If the number is the same, we set the information to 0, i could delete, but i would need to change the size of the array and the position of the pointers
            if(frecuency_list[i].number==frecuency_list[j].number){
                frecuency_list[j].frecuency=0;
                frecuency_list[j].number=0;
            }
        }
    }

    // Now with the data cleaned, we can calculate the number of bits needed to represent the list
    for(int i=0; i<size; i++){
        if(frecuency_list[i].number!=0){
            bits+=frecuency_list[i].number;
            bits++;
            bits+=frecuency_list[i].frecuency;
            bits++;
        }
    }

    // We remove the extra bit added to the end of the string
    bits--;

    // We return the number of bits
    return bits;
}

Frec.h

#ifndef FREC_H
#define FREC_H

// We create the struct of the frecuency representation
typedef struct Frec{
    char *bits;
    char *representaciones;
} Frec;

// This struct wiil be used to save the number of times that a number appears in the list
typedef struct Frecuency{
    int number;
    int frecuency;
}Frecuency;

int bits_frec(void *frec);
Frec *comprimir_en_frec(int n, int* grupo);
Frecuency *get_frecuency_representation(void *frec);

#endif
uwo
  • 25
  • 7
  • Two problems. Firstly, the return type of the function should be `Frecuency **`. That is, you need to return an array of pointers and not just a pointer. Secondly, `frecuency_list` is a local variable which becomes invalid as soon as the function exits so you must not return it to be used outside the function. `malloc` that as well so that the memory lifetime extends beyond the function liftetime. – kaylum Apr 23 '22 at 05:35

0 Answers0