我有一个参差不齐的二维结构数组和一个分配并返回mystruct*
的函数:
mystruct** arr;
mystruct* foo();
arr元素赋值的语法是什么?以下不起作用,但我想要类似的东西:
&arr[i][j]=foo();
这是一个简化的例子:
typedef struct mystruct{
int a,b,c,d;
} mystruct;
mystruct* foo()
{
mystruct* x = (mystruct*)malloc(sizeof(mystruct));
x->a=1;
x->b=1;
x->c=1;
x->d=1;
return x;
}
int main()
{
int rows=3;
int cols=4;
mystruct** arr;
arr = (mystruct**) malloc(sizeof(mystruct*)*rows);
for(int i=0;i<rows;i++)
{
arr[i]=(mystruct*)malloc(sizeof(mystruct)*cols);
}
for (int i=0;i<rows;i++)
{
*(arr[i][0]) = foo();
}
return 0;
}
我已经删除了我的大部分主程序,但上面的代码仍然给了我error: no match for ‘operator*’ (operand type is ‘mystruct’)
在实际代码中mystruct
很大,数组的尺寸很大。
答案 0 :(得分:1)
如果你真的希望mystruct
的所有实例都在一个分配中(即保持foo
不变)那么数组可以是:
int main()
{
int rows=3;
int cols=4;
mystruct *(*arr)[cols] = malloc( rows * sizeof *arr );
for(int i=0; i<rows; i++)
arr[i][0] = foo();
// note: arr[i][1] etc. are uninitialized
free(arr);
}
当每行的长度相同时,不需要为数组的每一行使用单独的malloc
,而是可以对一个块进行malloc。并don't cast malloc。
如果您不需要每行一次分配,并且您很乐意构造mystruct
void bar(mystruct *p)
,并使用指向某个已分配存储的指针调用mystruct
,那么您的数组可以存储{{1直接对象:
mystruct (*arr)[cols] = malloc( rows * sizeof *arr );
for ( int i = 0; i < rows; ++i )
bar( &arr[i][0] );
答案 1 :(得分:0)
*(arr[i][j]) = foo();
会将指向2d数组中struct的指针值设置为指向foo返回的struct,如果这是你真正想要的那样。
如果您只想保留2d到struct的指针数组,那么您可以将数组声明更改为mystruct* arr[3][4]
并使用arr[i][j] = foo()
。
答案 2 :(得分:-1)
我认为使用一些抽象将有助于这种情况。我急忙写了下面的例子,但我希望它有所帮助。
更新:根据评论更改。仍然在gcc下编译,现在干净地穿过Valgrind。
#include <stdio.h>
#include <stdlib.h>
typedef struct SomeStruct SomeStruct;
struct SomeStruct {
int foo;
int bar;
};
typedef SomeStruct* SomeStruct_ptr;
typedef struct SomeStructMat SomeStructMat;
typedef SomeStructMat* SomeStructMat_ptr;
struct SomeStructMat {
int rows;
int cols;
SomeStruct_ptr** data;
};
SomeStruct_ptr somestruct_new(int foo, int bar) {
SomeStruct_ptr ssp = malloc(sizeof(SomeStruct));
ssp->foo = foo;
ssp->bar = bar;
return ssp;
}
void somestruct_destroy(SomeStruct_ptr ssp) {
free(ssp);
}
SomeStruct_ptr** somestructmat_new(int rows, int cols) {
int r, c;
SomeStruct_ptr** mat = malloc( rows * sizeof(SomeStruct_ptr*) );
for(r = 0; r < rows; ++r) {
mat[r] = malloc(sizeof(SomeStruct_ptr) * cols);
for(c = 0; c < cols; ++c) {
mat[r][c] = somestruct_new(0,0);
}
}
return mat;
}
SomeStructMat_ptr SomeStructMat_new(int rows, int cols) {
SomeStructMat_ptr mat = malloc(sizeof(SomeStructMat));
mat->rows = rows;
mat->cols = cols;
mat->data = somestructmat_new(rows, cols);
return mat;
}
void SomeStructMat_destroy(SomeStructMat_ptr mat) {
int r,c;
for(r = 0; r < mat->rows; r++) {
for(c = 0; c < mat->cols; c++) {
free(mat->data[r][c]);
}
free(mat->data[r]);
}
free(mat->data);
free(mat);
}
int SomeStructMat_overwrite(SomeStructMat_ptr ssm, int r, int c, SomeStruct_ptr ssp) {
// TODO: Check that r and c are within bounds!
somestruct_destroy(ssm->data[r][c]);
ssm->data[r][c] = ssp;
}
void SomeStructMat_print(SomeStructMat_ptr mat) {
int r,c;
for(r = 0; r < mat->rows; r++) {
for(c = 0; c < mat->cols; c++) {
printf("[%d, %d] ", mat->data[r][c]->foo, mat->data[r][c]->bar);
}
printf("\n");
}
}
int main(int argc, char** argv) {
SomeStructMat_ptr ssm = SomeStructMat_new(2,3);
SomeStructMat_print(ssm);
printf("----------------\n");
SomeStructMat_overwrite(ssm, 0, 1, somestruct_new(5,6));
SomeStructMat_print(ssm);
printf("----------------\n");
SomeStructMat_destroy(ssm);
return 0;
}
更新:要在g ++下编译,你需要转换来自malloc的void指针。像这样:
#include <cstdio>
#include <cstdlib>
typedef struct SomeStruct SomeStruct;
struct SomeStruct {
int foo;
int bar;
};
typedef SomeStruct* SomeStruct_ptr;
typedef struct SomeStructMat SomeStructMat;
typedef SomeStructMat* SomeStructMat_ptr;
struct SomeStructMat {
int rows;
int cols;
SomeStruct_ptr** data;
};
SomeStruct_ptr somestruct_new(int foo, int bar) {
SomeStruct_ptr ssp = (SomeStruct_ptr) malloc(sizeof(SomeStruct));
ssp->foo = foo;
ssp->bar = bar;
return ssp;
}
void somestruct_destroy(SomeStruct_ptr ssp) {
free(ssp);
}
SomeStruct_ptr** somestructmat_new(int rows, int cols) {
int r, c;
SomeStruct_ptr** mat = (SomeStruct_ptr**) malloc( rows * sizeof(SomeStruct_ptr*) );
for(r = 0; r < rows; ++r) {
mat[r] = (SomeStruct_ptr*) malloc(sizeof(SomeStruct_ptr) * cols);
for(c = 0; c < cols; ++c) {
mat[r][c] = somestruct_new(0,0);
}
}
return mat;
}
SomeStructMat_ptr SomeStructMat_new(int rows, int cols) {
SomeStructMat_ptr mat = (SomeStructMat_ptr) malloc(sizeof(SomeStructMat));
mat->rows = rows;
mat->cols = cols;
mat->data = somestructmat_new(rows, cols);
return mat;
}
void SomeStructMat_destroy(SomeStructMat_ptr mat) {
int r,c;
for(r = 0; r < mat->rows; r++) {
for(c = 0; c < mat->cols; c++) {
free(mat->data[r][c]);
}
free(mat->data[r]);
}
free(mat->data);
free(mat);
}
int SomeStructMat_overwrite(SomeStructMat_ptr ssm, int r, int c, SomeStruct_ptr ssp) {
// TODO: Check that r and c are within bounds!
somestruct_destroy(ssm->data[r][c]);
ssm->data[r][c] = ssp;
}
void SomeStructMat_print(SomeStructMat_ptr mat) {
int r,c;
for(r = 0; r < mat->rows; r++) {
for(c = 0; c < mat->cols; c++) {
printf("[%d, %d] ", mat->data[r][c]->foo, mat->data[r][c]->bar);
}
printf("\n");
}
}
int main(int argc, char** argv) {
SomeStructMat_ptr ssm = SomeStructMat_new(2,3);
SomeStructMat_print(ssm);
printf("----------------\n");
SomeStructMat_overwrite(ssm, 0, 1, somestruct_new(5,6));
SomeStructMat_print(ssm);
printf("----------------\n");
SomeStructMat_destroy(ssm);
return 0;
}