[英]Reallocing nested array of structs in another struct in function
我正在嘗試將表(存儲在文件中)存儲到 memory 中。 為了簡單起見,我在這里有我編輯的代碼。 我遇到了分段錯誤,所以我認為它必須做一些事情,我嘗試存儲值而不實際聲明 arrays。 但我讀到它應該不是問題,因為 struct arrays 本身是動態的? 我真的不知道。 所以在 function addcelltoTable 我嘗試了一些重新分配,但沒有成功。 你能幫我理解 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;
}
在結構末尾用 [] 聲明的數組是一個靈活的結構數組,而不是指向數組的指針。 因此,您不能重新分配它(相反,您應該重新分配整個結構)。 因此,使用指向已分配 memory 的指針似乎更簡單。 這稍微改變了結構:
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;
您的分配代碼中有一個微妙的問題:當您分配一行時, rows->cells
數組包含垃圾,這使得對其調用的任何 function(包括 realloc)都會崩潰。 所以這些 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;
}
最后,您的 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.