我正在尝试将结构转换为另一个结构但是我在转换中存在不兼容的指针问题,而some_func
下的 malloc (结构布局是相同的)
struct stu1 **some_func(struct stu1 *my_struct)
{
my_struct = (struct stu1 **)malloc(sizeof(struct stu1 *)*total_size);
for(i=0;i<20;i++){
my_struct[i] = (struct stu1 *)malloc(sizeof(struct stu1));
printf("%s",my_struct[i++]->a);
}
return my_struct;
}
int main()
{
struct stu1 **my_struct;
struct stu2 **my_struct2;
struct stu3 **my_struct3;
my_struct = some_func(my_struct);
my_struct2 = (struct stu2**)some_func((struct stu1*)my_struct2);
my_struct3 = (struct stu3**)some_func((struct stu1*)my_struct3);
}
答案 0 :(得分:2)
几个问题。
首先,你到处都有不兼容的类型。在行
my_struct = some_func(my_struct);
my_struct
的类型为struct stu1 **
,但some_func
的定义需要struct stu1 *
类型的参数;这两种类型不一样。指向T的指针与指向T的指针的类型不同。
其次,你的铸造体操不会像你期望的那样发挥作用。指针类型不自动兼容;它们的基类型必须兼容,并且不同的结构类型不兼容,即使它们的布局相同,例如:
struct {int x, int y} foo;
struct {int x, int y} bar;
struct S {int x, int y} blurga;
struct S bletch;
foo
,bar
和bletch
属于不同类型且不兼容,即使它们的布局相同。 blurga
和bletch
属于同一类型(struct S)。如果struct stu2
或struct stu3
的大小与struct stu1
不同,则您不会为my_struct2
和my_struct3
分配适当的内存量。
为了清晰和理智,你应该为每种类型设置不同的分配功能,而不是试图将方形钉子压入五角形孔中:
struct stu1 **stu1_alloc(size_t count)
{
struct stu1 **arr = malloc(sizeof *arr * count);
if (arr)
{
size_t i;
for (i = 0; i < count; i++)
{
arr[i] = malloc(sizeof *arr[i]);
if (arr[i])
{
// initialize arr[i] as necessary
}
}
}
return arr;
}
struct stu2 **stu2_alloc(size_t count)
{
struct stu2 **arr = malloc(sizeof *arr * count);
if (arr)
{
size_t i;
for (i = 0; i < count; i++)
{
arr[i] = malloc(sizeof *arr[i]);
if (arr[i])
{
// initialize arr[i] as necessary
}
}
}
return arr;
}
struct stu3 **stu3_alloc(size_t count)
{
struct stu3 **arr = malloc(sizeof *arr * count);
if (arr)
{
size_t i;
for (i = 0; i < count; i++)
{
arr[i] = malloc(sizeof *arr[i]);
if (arr[i])
{
// initialize arr[i] as necessary
}
}
}
return arr;
}
int main(void)
{
struct stu1 **my_struct = stu1_alloc(SIZE);
struct stu2 **my_struct2 = stu2_alloc(SIZE2);
struct stu3 **my_struct3 = stu3_alloc(SIZE3);
...
}
是的,三个分配函数之间唯一不同的是类型。但是,如果不同的结构类型具有不同的大小或不同的初始化需求,那么这是必要的。
注意几件事。首先,我没有投出malloc()
的结果。有两个原因。一,从C89及更高版本开始,您不必:malloc()
返回void *
类型,它隐式转换为目标指针类型。第二,更重要的是,如果我忘记包含stdlib.h或者在范围内没有malloc()
原型,那么抛弃关闭将触发“不兼容类型”警告(因为未声明的函数被假定为返回int
,并且不能将int值隐式转换为指针类型。如果您转换malloc()
的返回值,那么您会在运行时压制该警告并冒险(因为malloc()
返回的值将从void *
转换为int
,然后从int
到目标指针类型,这不保证工作)。
其次,我在对象上使用sizeof
,而不是类型。这有两个好处。一,代码更容易阅读。第二,如果我改变对象的类型,我不必返回并改变每次调用malloc()
。
如果您 真的 不想拥有三个单独的分配函数,您可以尝试这样的宏魔术:
#define ALLOC_STU(target, size) \
do { \
target = malloc(sizeof *target * size); \
if (target) \
{ \
size_t i; \
for (i = 0; i < size; i++) \
{ \
target[i] = malloc(sizeof *target[i]); \
} \
} \
} while(0)
int main(void)
{
struct stu1 **my_struct;
...
ALLOC_STU(my_struct, SIZE);
...
}
虽然我认为单独的分配功能是更安全的方式。
答案 1 :(得分:1)
struct stu1 **some_func(struct stu1 *my_struct)
{
my_struct = (struct stu1 **)malloc(sizeof(struct stu1 *)*total_size);
my_struct
的类型为struct stu1 *
,但您尝试分配(已投放)struct stu1 **
答案 2 :(得分:0)
猜猜,你想要这样的东西:
struct stu1 **some_func(struct stu1 ***my_struct)
{
*my_struct = (struct stu1 **)malloc(sizeof(struct stu1 *)*total_size);
for(i=0;i<20;i++){
(*my_struct)[i] = (struct stu1 *)malloc(sizeof(struct stu1));
printf("%s",(*my_struct)[i++]->a);
}
return *my_struct;
}
int main()
{
struct stu1 **my_struct;
struct stu2 **my_struct2;
struct stu3 **my_struct3;
my_struct = some_func(&my_struct);
}
但这没有多大意义。返回值不是必需的。
答案 3 :(得分:0)
从哪里开始...
在some_func()中,似乎您可能正在尝试动态创建二维数组。作为参考,有两种方法可以使用malloc()。
方法#1。 (没有错误检查)
struct stu1 **some_func(int dim1, int dim2)
{
struct stu1 **my_struct;
int i;
/* Allocate space for an array of <dim1> pointers */
my_struct = (struct stu1 **) malloc(sizeof(struct stu1 *) * dim1);
/* Allocate <dim2> elements for each pointer */
for (i = 0; i < dim1; i++){
my_struct[i] = (struct stu1 *) malloc (sizeof (struct stu1) * dim2);
}
return (my_struct);
}
方法#2。 (再次,没有错误检查)
struct stu1 **some_func(int dim1, int dim2)
{
struct stu1 **my_struct;
int i;
char *data;
/* Allocate space for everything. */
data = (char *) malloc((sizeof (struct stu1 *) * dim1) + (dim1 * dim2 * sizeof (struct stu1)));
my_struct = (struct stu1 **) data;
/* Initialize pointers to pointers. */
data = (char *) &my_struct[dim1];
for (i = 0; i < dim1; i++) {
my_struct[i] = (struct stu1 *) data;
data += sizeof (struct stu1) * dim2;
}
return (my_struct);
}
每种方法都有其优点和缺点。希望这会有所帮助。