c struct指针问题

时间:2010-03-23 14:36:10

标签: c struct malloc

我正在尝试将结构转换为另一个结构但是我在转换中存在不兼容的指针问题,而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);    
}

4 个答案:

答案 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;

foobarbletch属于不同类型且不兼容,即使它们的布局相同。 blurgabletch属于同一类型(struct S)。如果struct stu2struct stu3的大小与struct stu1不同,则您不会为my_struct2my_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)

从哪里开始...

  1. 您必须匹配您的类型。 some_func()需要一个指针;在一个实例中,您传递的是双指针(指向指针的指针)。
  2. 在some_func()中,第一个malloc()的类型不匹配。它试图将双指针设置为单个指针。
  3. 在some_func()中,第二个malloc()有另一个类型不匹配。它试图将非指针(结构)设置为指针。
  4. 在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);
    }
    

    每种方法都有其优点和缺点。希望这会有所帮助。