Search code examples
carraysquicksortgenetic-algorithmshellsort

Sorting an array in c is deleting values


I am programming a genetic algorithm so that this solves problems of linear programming, I am using C language, when I calculate the limit of the variables I keep the values ​​in a float type array, I need to order that array but it deletes a data that I need to moment of ordering: I have used a shell_sort pogramed by me and the qsort that is implemented in the standard librarian and with both gives me the same result, I append the code of the algorithm that I use to order and the comparator function that I use for the qsort () :

    void shell_sort(float *A, int n){
    int gap = n/2;  //Se obtiene el gap dividiendo el tamaño de arreglo entre dos
    int inner, outer, swap; //Variables auxiliares

    while (gap > 0) { //Mientras gap sea mayor que zero entonces:
        for(outer = gap; outer < n; outer++){ // Para outer igual a gap, siempre que outer sea menor a n, outer aumentara su valor en uno
            inner = outer; // inner se iguala al valor de outer
            swap = A[inner]; // Swap se iguala a la posiscion inner de A
            while (inner > gap - 1 && A[inner - gap] > swap ) {  // Mientras inner sea mayor que gap menos 1 y que A en su posicion inner menos gap sea mayor a Swap
                A[inner] = A[inner - gap]; //La posicion inner de A tomara como nuevo valor la posicion inner menos  gap de A
                inner -= gap; //inner decrementa su valor en gap veces
            }
            A[inner] = swap; //La posicion inner de A tomo como nuevo valor swap
        }
        gap /=2; // se divide a gap entre dos
    }
}

Comparer function:

int comp(const void * a, const void * b){
    if(*(float*)a < *(float*)b) return -1;
    if(*(float*)a == *(float*)b) return 0;
    if(*(float*)a > *(float*)b) return 1;
}

Output: Output I think when I sort the array the result will be 0,26,37 but the result is 26,37 and I need that zero I don't really know why is this happen.

Hope someone can help me.

This is the piece of code when I use the sorting.

    Limites obtenerValoresLimites(lista *l,char var){
        //This code works
Limites lim;
        restriccion r;
        int i,j;
        float *aux = (float*)malloc(sizeof(float));
        for (i = 0; i < Size(l); i++)
        {
            r = Element(l,i+1);
            for (j = 0; j < strlen(r.variables); j++)
            {
                if(r.variables[j] == var){
                    aux[i] = (r.limite/r.coeficientes[j]);
                    }
            }
        }
    //First print of the output that confirms the zero originally exist

        //for (i = 0; i < sizeof(aux)/sizeof(*aux) ;i++)
            //printf("%f\n",aux[i]);

    //Sorting
        //qsort(aux,sizeof(aux)/sizeof(*aux)+1,sizeof(float),comp);
        shell_sort(aux,sizeof(aux)/sizeof(*aux));

        //printf("\n");
    //Second print of the output now the zero is no longer in the array
        //for (i = 0; i < sizeof(aux)/sizeof(*aux) ;i++)
        //{
        //  printf("%f\n",aux[i]);
        //}

        lim.inferior = 0;
        lim.superior = aux[(sizeof(aux)/sizeof(*aux))-1];
        lim.variable = var;

        return lim;
    }

Thanks for answer and read.

I think the code is a little bit difficult to read, its because we are using some data structures to modelete the problem so if you are interested in we leave the gitHub repo below.

Complete code if you are interesed in: https://github.com/JoelRomero97/Metodos-Cuantitativos.git


Solution

  • Like I suspected, the problem is in how you call the sorting function.

    shell_sort(aux,sizeof(aux)/sizeof(*aux));
    

    The sizeof(aux)/sizeof(*aux) construct works only for pure arrays, not for pointers (and also not for pointers that point to allocated memory). When you allocate memory with malloc & friends, you know beforehand the size, store it in a variable and use that variable for when you call the sorting function or any other function that expects the size of the array.

    Because sizeof(aux)/sizeof(*aux) is wrong, your are accessing memory beyond the limits, so this yields undefined behaviour. And that is also true before you even call the sorting function. You are are doing

    aux[i] = (r.limite/r.coeficientes[j]);
    

    for values of i larger than 1 (assuming that Size(l) is larger than 1).

    You have to allocate the proper amount of memory, base on your code, I presume you need Size(l) spaces. So the correct allocation should be

    size_t len = Size(l);
    float *aux = malloc(len * sizeof *aux);
    if(aux == NULL)
    {
        fprintf(stderr, "Not enough memory\n");
        return SOME_ERROR_VALUE;
    }
    
    for (i = 0; i < len; i++)
    {
        ...
    }
    
    shell_sort(aux, len);
    
    ...
    
    lim.inferior = 0;
    lim.superior = aux[len-1];
    lim.variable = var;
    

    Also, don't cast malloc