c - c中内存的重新分配/分配

标签 c memory

该程序的作用: 从文件中读取一个包含 nrRows 行和 nrColomns 列的矩阵(二维数组)。 矩阵的所有元素都是 [0,100) 之间的整数。 程序必须重新排列矩阵内的所有元素,使每个元素等于其所在行的索引。

例如。 5 将位于第 5 行(行),58 将位于第 58 行。

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

例如。 3 行 2 列。不是 3 行,其中第 1 行有 1 列,第 2 行有 3 列,依此类推。

我认为重新分配在我的 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

最佳答案

我一直讨厌重新分配。如果您可以避免它,我的建议如下:

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

  • 在 C 语言中,最好在任何函数的开头声明所有变量。如果可能,切勿在代码中间声明变量。
  • 您可以在 for block 内声明变量。然而,它并不适用于所有版本的 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] )。另外,抱歉英语不好^^'

关于c - c中内存的重新分配/分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48270955/

相关文章:

php - 逐个加载 XML,以节省 PHP 内存

c - C程序如何在不轮询内核的情况下获取新添加的NIC的pci地址?

c - 用C程序访问sqlite

c - 二分查找 - 如果我从列表中间添加或减去 "1",我会得到中间数字左边的第一个数字还是一个数值?

c - 如何在 C 中打印 "unsigned long"?

windows - Windows 任务管理器中我的 MMF(内存映射文件)内存在哪里?

python - 对不适合内存的集合进行 Daskcompute()

c - 如何跳过一个值并转到 fscanf() 中的下一个值,以及如何 fscanf() 特定类型

memory - Cuda:如果我只使用 .x 的 block 和线程,它是否仍会使用 GPU 中的所有可用线程,还是必须使用 .y 和 .z 的线程和 block ?

memory - 在不复制内存的情况下重复 pytorch 张量