简体   繁体   English

在 function 的另一个结构中重新分配嵌套的结构数组

[英]Reallocing nested array of structs in another struct in function

I'm trying to store table(stored in a file) into memory.我正在尝试将表(存储在文件中)存储到 memory 中。 I have here my edited code for simplicity.为了简单起见,我在这里有我编辑的代码。 Im running into segmentation fault so I think it has to do something with that I try to store values without declaring the arrays actually.我遇到了分段错误,所以我认为它必须做一些事情,我尝试存储值而不实际声明 arrays。 But I read it shouldn't be a problem as struct arrays are dynamic on their own?但我读到它应该不是问题,因为 struct arrays 本身是动态的? I don't really know.我真的不知道。 So in function addcelltoTable I tried some reallocating, but unsuccessfully.所以在 function addcelltoTable 我尝试了一些重新分配,但没有成功。 Can you help me understand memory allocating and maybe pointers a little more?你能帮我理解 memory 分配和指针更多一点吗?

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include <errno.h>
typedef struct Cells
{
    bool selected;
    char *Content;
} cell;

typedef struct Rows
{
    int someint;
    cell cells[];
} row;
typedef struct Tables
{
    int NumberOfColumns;
    int NumberOfRows;
    row rows[];

} table;
void addCellToTable(table *dataTable, char *cellContent, int row, int column)
{
    if (row > dataTable->NumberOfRows)
    {
        dataTable->NumberOfRows = row;
    }
    if (column > dataTable->NumberOfColumns)
    {
        dataTable->NumberOfColumns = column;
    }
    *dataTable->rows[row].cells = (cell*)realloc(dataTable->rows[row].cells, column*sizeof(char*)+1);  //here I'm trying to realloc array of cells , error: incompatible types when assigning to type ‘cell’ {aka ‘struct Cells’} from type ‘cell *’ {aka ‘struct Cells *’}
    //*dataTable->rows = (row*)realloc(dataTable->rows, (sizeof(dataTable->rows)*sizeof(char*))); //realloc array of rows ?
    *dataTable->rows[row].cells[column].Content = *cellContent;
    printf("%d : %d : %lu : %s\n", row, column, strlen(dataTable->rows[row].cells[column].Content), dataTable->rows[row].cells[column].Content);
}
int main()
{
    char numberitoa[10];
    table dataTable;
    /*dataTable.NumberOfColumns=0;
    dataTable.NumberOfRows=0;
    dataTable.rows[0].someint=0;
    dataTable.rows[0].cells[0].selected=false;
    dataTable.rows[0].cells[0].Content="";*/
    for (int i = 0; i < 5; i++)
    {
        for (int j = 0; j < 5; j++)
        {
            sprintf(numberitoa, "%d", rand());
            addCellToTable(&dataTable, numberitoa, i, j);
        }
    }
    for (int i = 0; i < dataTable.NumberOfColumns + 1; i++)
    {
        for (int j = 0; j < dataTable.NumberOfRows + 1; j++)
        {
            printf("main: %d, %d, %s\n", i, j, dataTable.rows[i].cells[j].Content);
        }
        printf("\n");
    }
    return 0;
}

An array declared with [] at the end of a structure is a flexible structure array, not a pointer to an array.在结构末尾用 [] 声明的数组是一个灵活的结构数组,而不是指向数组的指针。 Consequently you cannot reallocate it (instead you should reallocate the whole structure).因此,您不能重新分配它(相反,您应该重新分配整个结构)。 Therefore it seems simpler to use a pointer to the allocated memory.因此,使用指向已分配 memory 的指针似乎更简单。 This slightly changes the structures:这稍微改变了结构:

typedef struct Cell
{
    // You cannot use the same storage for each string as you did
    // instead we can use a fixed sized string (no allocation required)
    char Content[10]; 
    bool selected;

} cell;

typedef struct Rows
{
    int someint;
    cell * cells;
} row;
typedef struct Tables
{
    int NumberOfColumns;
    int NumberOfRows;
    row * rows;

} table;

There was a subtle issue in your allocation codes: when you allocate a row, the rows->cells array contains garbage, which makes any function called on it (including realloc) subject to crash.您的分配代码中有一个微妙的问题:当您分配一行时, rows->cells数组包含垃圾,这使得对其调用的任何 function(包括 realloc)都会崩溃。 So these arrays must be set to NULL immediately after the rows have been allocated.所以这些 arrays 必须在行分配后立即设置为 NULL。

void addCellToTable(table *dataTable, char * cellContent, int row, int column)
{ 
    if (dataTable->NumberOfRows != row + 1) {
        dataTable->rows = realloc(dataTable->rows, (row + 1) * sizeof(struct Rows));
        for (int i=0; i <= row; i++) dataTable->rows[i].cells = NULL; //<== here
    }
    if (dataTable->NumberOfColumns != column + 1)
        dataTable->rows[row].cells = realloc(dataTable->rows[row].cells, (column + 1) * sizeof(struct Cell));
    
    // The fixed sized string must be set with memcpy
    memcpy(dataTable->rows[row].cells[column].Content, cellContent, strlen(cellContent) + 1);
    
    dataTable->NumberOfRows = row + 1;
    dataTable->NumberOfColumns = column + 1;
}

Finally your arrays are reallocated at each iteration so the print statement should be in the same loop than the allocations otherwise you cannot print all allocated cells.最后,您的 arrays 在每次迭代时都会重新分配,因此打印语句应该与分配在同一个循环中,否则您无法打印所有分配的单元格。

int main()
{
    char numberitoa[10];
    table dataTable = {0};
    for (int i = 0; i < N; i++)
    {
        for (int j = 0; j < N; j++)
        {
            sprintf(numberitoa, "%d", rand() % 1000);
            addCellToTable(&dataTable, numberitoa, i, j);

            printf("main: %d, %d, %s\n", i, j, dataTable.rows[i].cells[j].Content);
        }
    }
    return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM