在C中为结构指针数组成员分配地址

teh*_*rus 2 c arrays struct pointers variable-assignment

一些指针算术有相当大的麻烦.我我得到了概念(指针变量指向内存地址,正常变量指向数据)但我相信我的问题是语法(*, &, (*), *(),等)

我想要做的是构建一个自定义结构的动态数组(即指向堆结构的指针数组),我的接口提供两个方法,"ad_to_obj_array"(它接受要添加的对象,以及可以为null的数组为空)和"obj_array_dustbin"(它只是处理数组,也处理内容,堆objs).前者呈现如下.

对象的细节并不重要(并且结构已经被重命名)但是我对一般问题的解决方案如下,如果您能发现错误,我将不胜感激.编译器抱怨无效的左值,我尝试将RHS上的指针中的地址分配给堆结构指针数组中的指针值:

#define NUM_ELEM(x) (sizeof (x) / sizeof (*(x)))

obj* add_to_obj_array(obj* new_obj, obj* array)
{
  int number_of_elements = 0;
  if (array != NULL)
  {
    number_of_elements = NUM_ELEM(array);
  }

  obj* new_array = NULL;

  /* note: I am expecting sizeof(new_obj) to return the size of an obj* 
     to go into the array of pointers. */
  if ( NULL ==
       (new_array = (obj*)malloc((number_of_elements + 1)* sizeof(new_obj))) )
  {
    /* memory request refused :( */
    return NULL;
  }

  /* copy the old array pointers into the new array's pointer slots: */
  int i;
  for (i = 0; i < number_of_elements; i++)
  {
    &(new_array[i]) = &(array[i]);
  }

  /* add the new item to the end (assign pointer value directly): */
  new_array[number_of_elements] = new_obj;

  if (number_of_elements > 0)
  {
    free(&array);
  }

  return new_array;
}
Run Code Online (Sandbox Code Playgroud)

现在,我尝试了以下违规行的排列:

  &(new_array[i]) = &(array[i]);
  *(new_array[i]) = &(array[i]);
  new_array[i] = &(array[i]);
Run Code Online (Sandbox Code Playgroud)

并且都给出了一种或另一种编译器错误.我相当确定右侧是旧数组的第i个元素的地址,但是当数组的元素是指向结构的指针时,如何分配给new的第i个元素?

编辑 - 请注意,上面的宏NUM_ELEM不起作用; 它将永远返回1.请参阅@Merlyn Morgan-Graham的答案,了解原因.

Jer*_*fin 8

根据你的描述,你开始没错,所以当你复制东西时,你所能做的一切都可能有效.

现在,你已经定义了new_array(并且可能是array)作为指针obj.结果如下:

替代文字

在这种情况下,您有一个指向动态分配的对象数组的指针.当/如果扩展分配时,您需要自己复制所有对象.

根据你的描述:"(即指向堆结构的指针数组)",你想要的是一个指针数组.如果要自动分配该指针数组,您的定义将如下所示:

obj *array[NUMBER];
Run Code Online (Sandbox Code Playgroud)

我的猜测是,这不是你想要的.据推测,您也希望动态分配该数组.这看起来像这样:

替代文字

在这种情况下,new_arrayarray将每一个需要被定义为一个指针指向obj.然后,您将分配一个指针数组(即指向obj您想要的多个指针),并将每个指针指向obj:

obj **new_array;

// allocate an array of pointers with space to point at more items:    
new_array = malloc(sizeof(obj *) * new_elements);

// copy the pointers to the current items to the new array:
for (i=0; i<current_elements; i++)
    new_array[i] = array[i];
Run Code Online (Sandbox Code Playgroud)

这样做的好处是,当您进行复制时,您只复制指针,而不是对象本身.特别是对于大型物体,这可以节省大量的精力.代价是,使用的元件通过一个间接这一翻译的两级去,因此参考可能比较慢(虽然很少慢,特别是在相对高性能的处理器).

正如@rerun已经指出的那样,在任何一种情况下你都可能想要使用realloc.特别是,这可能能够"就地"扩展分配,并避免经常复制数据.当然,这不是保证,但至少你给它一个机会; 如果你malloc每次复制,你甚至可以消除优化的可能性.