c中重新分配/分配内存

时间:2018-01-15 21:32:48

标签: c memory

该计划的作用: 从文件中读取带有nrRows行和nrColomns colomns的矩阵(2d数组)。 矩阵的所有元素都是[0,100]之间的int数。 程序必须重新排列矩阵内的所有元素,使每个元素等于它所在行的索引。

离。 5将在第58行的第5行,第58行。

结果写在一个文件中。 我只需要使用1个矩阵,所有内存都是动态分配的。 如果我必须添加或擦除元素,我也会重新调整矩阵的内存。 另外,我需要保持矩阵的形状。

离。 3排2个colomns。不是3行,其中第1行有1个colomn,第2行有3个colomns等。

我认为重新分配在我的c程序中不起作用。该程序本身工作正常。 帮助

#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);

}

这很奇怪......我在这个问题上已经失去了足够的时间。

test.txt的例子

  

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

1 个答案:

答案 0 :(得分:0)

我总是讨厌realloc。如果你可以避免它,请按照我的建议:

有关您的代码的一些要点,无论问题如何:

  • 在C中,最好在任何函数的开头声明所有变量。如果可能,永远不要在代码中间声明变量。
  • 您可以在for块内声明变量。但是它在所有版本的C中都不起作用。取决于编译器。
  • 除非您在内存非常有限的设备上部署此代码,否则您无需使用unsigned short。经典整数可以。
  • 建议检查每个malloc是否顺利。如果没有,做必要的行动以避免崩溃。

代码:

#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);
}

注意:我没有尝试编译它,它可能有错误(特别是在(*currentArray)[i][j]之类的东西上)。对不起英语不好^^&#39;