C 二维数组函数的重新分配

C Reallocation of 2d array function

我的重新分配不起作用(Segmentation fault for 11.element),我想将数组扩大两倍,列的长度根据第一个input.I想分配在功能上。 在函数 vztvorPole 中,我分配了一个 10 行 x 列的数组。

 char vytvorPole(char ***grid, int nrows, int ncols)
{
    *grid = malloc( sizeof(*grid)*nrows);
    
    if (*grid == NULL)
    {
        printf("ERROR\n");
        return 1;
    }
    
    for(int i=0;i<nrows;i++)
    {
        (*grid)[i]=(char *) malloc (ncols*sizeof(*grid));
        if((*grid)[i] == NULL)
        {
            printf("ERROR\n");
        return 1;
        }
    }
    return 0;
}
    char realokuj(char ***grid, int nrows, int ncols)
    {
        char **docasne;
        docasne = (char**)realloc (*grid, nrows*sizeof(*grid));
        
        for(int i=nrows/2;i<nrows;i++)
        {
            (docasne)[i]=(char *) malloc (ncols*sizeof(*grid));
            
        }
        *grid = docasne;
    }
    int main (void)
    {
        char **diagonaly;
        int rDiagonaly = 10;
        int cDiagonaly = -1;
    
        char *str = NULL;
        size_t  capacity = 0;
        int first = 1;
        int nr = 0;
        
        printf("Vypln:\n");
        while ( getline (&str, &capacity, stdin) != -1)
        {
            if(str[0] == '\n')
                    break;

            if (first)
            {
                cDiagonaly = strlen (str);
                vytvorPole(&diagonaly, rDiagonaly, cDiagonaly);
                first = 0;
            }   
        
            if (nr==rDiagonaly)
                {
                    rDiagonaly *= 2; 
                    realokuj(&diagonaly, rDiagonaly, cDiagonaly);
                }
            
            strcpy(diagonaly[nr],str);
            nr++;
            
        }
    
    }

您的代码比需要的要复杂一些。

如果你初始化 diagnonaly(例如char **diagnoaly = NULL;),你可以消除vytvorPole并只使用realokuj。也就是说,如果您还这样做:int rDiagonaly = 0;

那是因为 realloc 可以很好地处理 NULL 指针(即在这种情况下它等同于 malloc)。

而且,你不需要做:

(docasne)[i]=(char *) malloc (ncols*sizeof(*grid));

在子函数中。

最好在main中使用strdup。如果我们这样做,我们根本不需要 cDiagonaly。而且,我们可以有不同长度的字符串。

传递三重星指针(例如 char ***grid)有问题。您可以将其作为 char ** 传递并使用 return 来更新该值,因为您并没有真正使用现有的 return.

但是,这真的可以从 main 完成,而无需 一个单独的函数。

虽然 可能 可以修复您现有的代码,但确实应该对其进行简化:

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

int
main(void)
{
#if 0
    char **diagonaly;
    int rDiagonaly = 10;
#else
    char **grid = NULL;
    int rmax = 0;
#endif
#if 0
    int cDiagonaly = -1;
#endif

    char *str = NULL;
    size_t capacity = 0;
#if 0
    int first = 1;
#endif
    int nr = 0;

    printf("Vypln:\n");
    while (getline(&str,&capacity,stdin) != -1) {
        if (str[0] == '\n')
            break;

        if (nr == rmax) {
            rmax += 100;

            grid = realloc(grid,sizeof(*grid) * (rmax + 1));
            if (grid == NULL) {
                perror("realloc");
                exit(1);
            }

            // this is similar to what you did, but it's not necessary because
            // of "grid[nr] = NULL;" below
#if 0
            for (int idx = nr;  idx < rmax;  ++idx)
                grid[idx] = NULL;
#endif
        }

        grid[nr++] = strdup(str);
        grid[nr] = NULL;
    }

    return 0;
}

这是清理后的版本 [没有 cpp 条件]:

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

int
main(void)
{
    char **grid = NULL;
    int rmax = 0;

    char *str = NULL;
    size_t capacity = 0;
    int nr = 0;

    printf("Vypln:\n");
    while (getline(&str,&capacity,stdin) != -1) {
        if (str[0] == '\n')
            break;

        if (nr == rmax) {
            rmax += 100;

            grid = realloc(grid,sizeof(*grid) * (rmax + 1));
            if (grid == NULL) {
                perror("realloc");
                exit(1);
            }
        }

        grid[nr++] = strdup(str);
        grid[nr] = NULL;
    }

    return 0;
}

这样可以吗?

while ( getline (&str, &capacity, stdin) != -1)
    {
        if(str[0] == '\n')
            break;
        
        
        if (first)
        {
            cDiagonaly = strlen (str);
            diagonaly = (char**) malloc(sizeof(*diagonaly)*rDiagonaly);
            
        
        if (nr==rDiagonaly)
            {
                rDiagonaly *= 2; 
                docasne = (char**)realloc (diagonaly, rDiagonaly*sizeof(*diagonaly));
                diagonaly=docasne;
            }
        
        diagonaly[nr]=(char*) malloc (cDiagonaly*sizeof(**diagonaly));
        strcpy(diagonaly[nr],str);
        
        nr++;
        
    }