0

What the program does: Reads from a file a matrix (2d Array) with nrRows rows and nrColomns colomns. All elements of the matrix are int numbers between [0,100). The program has to rearrange all of the elements inside the matrix such that each element is equal to the index of the row it is in.

ex. 5 will be on line(row) 5, 58 on row 58.

The result is written in a file. I need to use only 1 matrix and all memory is allocated dynamically. If I have to add or erase elements, I also readjust the memory of the matrix. Also, I need to keep the shape of a matrix.

ex. 3 rows with 2 colomns. NOT 3 rows where row 1 has 1 colomn, row 2 has 3 colomns, etc..

I think reallocation doesn't work in my c program. The program itself works fine. Help?

#include<stdio.h>
#include<malloc.h>

unsigned short maxim(unsigned short A[100])
{
    unsigned short max = 0;

    for (unsigned short i = 0; i<100; ++i)
        if (A[i] > max)
            max = A[i];
    return max;
}

void main()
{
    FILE *pFile = fopen("test.txt", "r");
    unsigned short nrRows, nrColomns;

    /* If empty exit */
    if (pFile == NULL)
        return;

    fscanf(pFile, "%d", &nrRows);
    fscanf(pFile, "%d", &nrColomns);

    /* Memory Allocation */
    int** V = (int**)malloc(nrRows * sizeof(int*)); /* Number of lines */
    for (unsigned short i = 0; i < nrRows; ++i)
        V[i] = (int*)malloc(nrColomns * sizeof(int)); /* Number of colomns */

    /* Read the elements */
    for (unsigned short i = 0; i < nrRows; ++i)
        for (unsigned short j = 0; j < nrColomns; ++j)
            fscanf(pFile, "%d", &V[i][j]);


    /* Find max + array */
    unsigned short A[100] = { '\0' }; unsigned short max = 0;

    for (unsigned short i = 0; i < nrRows; ++i)
        for (unsigned short j = 0; j < nrColomns; ++j)
        {
            /* How many times each value between [0 and 100) is found inside the matrix */
            A[V[i][j]]++;

            /* Find the biggest element */
            if (V[i][j] > max)
                max = V[i][j];
        }

    /* Memory Reallocation */
    unsigned short maxA = maxim(A); unsigned short ok = 0;

    if (maxA > nrColomns){
        nrColomns = maxA;
        ok++;
    }
    if (max + 1 > nrRows){
        nrRows = max + 1;
        ok++;
    }

    //if (ok != 0)
    //{
        *V = realloc(*V, nrRows * sizeof(int*));
        for (unsigned short i = 0; i < nrRows; i++)
            V[i] = (int*)realloc(V, nrColomns * sizeof(int));
    //}

    /* Rearrange Values */
    unsigned short bool = 1;
    while (bool != 0)
    {
        bool = 0;
        for (unsigned short i = 0; i < nrRows; ++i)
        {
            for (unsigned short j = 0; j < nrColomns; ++j)
            {
                if (V[i][j] != i)
                {   
                    /* Swap elements */
                    unsigned short k = 0;
                    while (k < nrColomns)
                    {
                        if (V[V[i][j]][k] != V[i][j])
                        {
                            bool = 1;

                            /* Do the swapping */
                            int swap = V[V[i][j]][k];
                            V[V[i][j]][k] = V[i][j];
                            V[i][j] = swap;

                            break;
                        }
                        else k++;

                    }
                }
            }
        }
    }

    /* Extra Reallocation */
    if (maxA < nrColomns)
    {
        nrColomns = maxA;
        for (unsigned short i = 0; i < nrRows; ++i)
            V[i] = (int*)realloc(V, nrColomns * sizeof(int));
    }

    /* Print Result into file */
    pFile = fopen("out.txt", "w");

    fprintf(pFile, "%d %d \n", nrRows, nrColomns);

    for (unsigned short i = 0; i < nrRows; ++i)
    {
        for (unsigned short j = 0; j < nrColomns; ++j)
            fprintf(pFile, "%d ", V[i][j]);

        fprintf(pFile, "\n");
    }
    fclose(pFile);


    _getch();

    /* Memory Deallocation */
    for (unsigned short i = 0; i < nrRows; ++i)
        free(V[i]);
    free(V);

}

It's just wierd... I've lost enough hours on this problem.

Example of test.txt

4 3 1 2 2 0 0 0 1 1 3 5 3 2

Pusky
  • 1
  • 2

1 Answers1

0

I always hated realloc. If you are ok to avoid it, here's what I suggest :

Some points about your code, regardless of the problem :

  • in C it is better to declare all the variables at the start of any function. If possible, never declare a variable in middle of the code.
  • You can declare variable inside for block though. However it doesn't work in all version of C. Depends on the compiler.
  • Unless you will deploy this code on some device with really limited memory, you don't necessary have to use unsigned short. Classic integers would do.
  • It is recommended to check if every malloc went well. And if not, to do the necessary actions to avoid crash.

Code :

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

int min(int a, int b) {
    return (a < b) ? a : b;
}

void updateDimensions(int*** currentArray, unsigned short currentRowsNb, unsgined short currentColumnsNb, unsigned short newRowsNb, unsigned short newColumnsNb) {
    int i;
    int j;
    int error;
    int** res;

    if(*currentArray != NULL && (newRowsNb != currentRowsNb || newColumnsNb != currentColumnsNb)) {
        error = 0;

        /* Memory allocation */
        res = (int**)malloc(newRowsNb* sizeof(int*));
        if(res != NULL) {
            for(i=0 ; i < newRowsNb; i++) {
                res[i] = (int*)malloc(newColumnsNb* sizeof(int));
                if(res[i] == NULL) {
                    error = 1;
                    fprintf(stderr, "allocation error");    // Optional
                    while(--i >= 0)
                        free(res[i]);
                    free(res);
                }
            }
        } else {
            fprintf(stderr, "Allocation error);
            error = 1;
        }
        /* End of memory allocation */

        if(!error) {
            /* Copy of the array */
            for(i=0 ; i < min(currentRowsNb, newRowsNb) ; i++)
                for(j=0 ; j < min(currentColumnsNb, newColumnsNb) ; j++)
                    res[i][j] = (*currentArray)[i][j];
            /* End of copy */

            /* Free current array */
            for(i=0 ; i < currentNrRows ; i++)
                free((*currentArray)[i]);
            free(*currentArray);
            /* End of free */

            *currentArray = res;    // Assign new array to current one.
        }
    }
}



unsigned short maxim(unsigned short A[100]) {
    unsigned short max = 0;
    unsigned short i;

    for(i = 0 ; i < 100 ; i++)
        if(A[i] > max)
            max = A[i];
    return max;
}

void main() {
    /* Variable declaration */
    unsigned short i;
    unsigned short j;
    unsigned short k;
    unsigned short ok;
    unsigned short max;
    unsigned short maxA;
    unsigned short nrRows;
    unsigned short my_bool;
    unsigned short nrColomns;
    unsigned short A[100];
    int swap;
    int newNrRows;
    int newNrColumns;
    int tempInt;
    int **V;
    FILE *pFile;

    /* Variable initialization */
    pFile = fopen("test.txt", "r");
    if(pFile == NULL)
        return;

    fscanf(pFile, "%d", &nrRows);
    fscanf(pFile, "%d", &nrColomns);

    max = 0;
    my_bool = 1;
    for(i=0 ; i < 100 ; i++)
        A[i] = '\0';


    /* Memory Allocation */
    V = (int**)malloc(nrRows * sizeof(int*)); /* Number of lines */
    if(V == NULL) {
        fprintf(stderr, "Allocation error");    // Writes in the error output (optional)
        return;
    }
    for (i = 0; i < nrRows; ++i)
        V[i] = (int*)malloc(nrColomns * sizeof(int)); /* Number of colomns */
        /* If allocation error */
        if(v[i] == NULL) {
            fprintf(stderr, "Allocation error");    // Optional
            /* The following is mandatory */
            while(--i > 0) {    // Free all cell already allocated
                free(A[i]);
            }
            free(A);
            return;
        }
    }
    /* End of memory allocation */

    /* Read the elements */
    for (i = 0; i < nrRows; ++i)
        for (j = 0; j < nrColomns; ++j)
            fscanf(pFile, "%d", &V[i][j]);    // That assume you only have digit (0 to 9) in your file.
            /* If you have a delimiter between numbers (here i'll take ';' as example, use this */
            fscanf(pFile, "%[^;]%*d", &v[i][j]);
            /* If you have many delimiters (here ';', ' ' and '\n' as example) */
            fscanf(pFile, "%[^;\n ]%*d", &v[i][j]);
    /* End of reading


    /* Find max + array */
    for (i = 0; i < nrRows; ++i)
        for (j = 0; j < nrColumns; ++j) {
            /* How many times each value between [0 and 100) is found inside the matrix */
            A[V[i][j]]++;

            /* Find the biggest element */
            if (V[i][j] > max)
                max = V[i][j];
        }

    /* Memory Reallocation */
    maxA = maxim(A);

    if (maxA > nrColomns) {
        newNrColumns = maxA;
        ok++;
    }
    if (max + 1 > nrRows) {
        newNrColumns = max + 1;
        ok++;
    }

    if (ok != 0) {
        updateDimensions(&V, nrRows, nrColumns, newNrRows, newNrColumns);
        nrRows = newNrRows;
        nrColumns = newNrColumns;
    }

    /* Rearrange Values */
    while (my_bool != 0) {
        my_bool = 0;
        for (i = 0; i < nrRows; ++i) {
            for (j = 0; j < nrColomns; ++j) {
                if (V[i][j] != i) {   
                    /* Swap elements */
                    k = 0;
                    while (k < nrColomns) {
                        if (V[V[i][j]][k] != V[i][j]) {
                            my_bool = 1;
                            /* Do the swapping */
                            swap = V[V[i][j]][k];
                            V[V[i][j]][k] = V[i][j];
                            V[i][j] = swap;

                            break;
                        } else {
                            k++;
                        }

                    }
                }
            }
        }
    }

    /* Extra Reallocation */
    if (maxA < nrColomns) {
        newNrColumns = maxA;
        updateDimension(&V, nrRows, nrColumns, newNrRows, newNrColumns);
    }

    /* Print Result into file */
    fclose(pFile);
    pFile = fopen("out.txt", "w");
    if(pFile == NULL) {
        fprintf(stderr, "Error while openning file");
    } else {
        fprintf(pFile, "%d %d \n", nrRows, nrColomns);
        for (unsigned short i = 0; i < nrRows; ++i) {
            for (unsigned short j = 0; j < nrColomns; ++j)
                fprintf(pFile, "%d ", V[i][j]);

            fprintf(pFile, "\n");
        }
        fclose(pFile);
    }


    _getch();

    /* Memory Deallocation */
    for (i = 0; i < nrRows; ++i)
        free(V[i]);
    free(V);
}

NB : I did not try to compile this, it might have errors (especially on things like : (*currentArray)[i][j] ). Also, sorry for bad English ^^'

Insonore
  • 116
  • 6