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的答案,了解原因.
根据你的描述,你开始没错,所以当你复制东西时,你所能做的一切都可能有效.
现在,你已经定义了new_array
(并且可能是array
)作为指针obj
.结果如下:
在这种情况下,您有一个指向动态分配的对象数组的指针.当/如果扩展分配时,您需要自己复制所有对象.
根据你的描述:"(即指向堆结构的指针数组)",你想要的是一个指针数组.如果要自动分配该指针数组,您的定义将如下所示:
obj *array[NUMBER];
Run Code Online (Sandbox Code Playgroud)
我的猜测是,这不是你想要的.据推测,您也希望动态分配该数组.这看起来像这样:
在这种情况下,new_array
和array
将每一个需要被定义为一个指针指向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
每次复制,你甚至可以消除优化的可能性.