根据你的comment,你已经非常接近你想要的了。
使用结构数组
这是对您的代码的改编。主要变化是使用ArrayOfStructs *array,而不是使用指向指针的指针。此外,由于您已决定使用 uint_fast64_t 作为数据类型,因此您必须使用来自 <inttypes.h> 的 PRIuFAST64 来获取正确的格式字符串。最好改成size_t;您不会在任何合理的系统上发现性能差异(但代码使用格式PRIuFAST64)。
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <inttypes.h>
typedef struct
{
double X;
double Y;
} ArrayOfStructures;
typedef struct
{
uint_fast64_t length;
ArrayOfStructures *array;
} Points;
typedef struct
{
Points *points;
} Config;
static
void add_new_array(Config *conf)
{
printf("conf=%p\n", conf);
printf("conf->points=%p\n", conf->points);
printf("conf->points->length=%" PRIuFAST64 "\n", conf->points->length);
printf("conf->points->array=%p\n", conf->points->array);
ArrayOfStructures *temp = calloc(conf->points->length, sizeof(ArrayOfStructures));
printf("temp=%p\n", temp);
conf->points->array = temp;
printf("conf->points->array=%p\n", conf->points->array);
}
static
void another_function(Config *conf)
{
conf->points->length = 1;
add_new_array(conf);
conf->points->array[0].X = 0.1;
conf->points->array[0].Y = 0.2;
printf("The result: X=%.12f, Y=%.12f, length=%" PRIuFAST64 "\n",
conf->points->array[0].X, conf->points->array[0].Y, conf->points->length);
}
static
void some_function(Config *conf)
{
// To pass the structure to another function
another_function(conf);
}
int main(void)
{
// Stack's allocated memory
Config conf_;
Config *conf = &conf_;
memset(conf, 0x0, sizeof(Config));
// Stack's allocated memory
Points points;
memset(&points, 0x0, sizeof(Points));
conf->points = &points;
some_function(conf);
return(EXIT_SUCCESS);
}
运行时,会产生:
conf=0x7ffeed6883f8
conf->points=0x7ffeed688400
conf->points->length=1
conf->points->array=0x0
temp=0x7fef13c02a80
conf->points->array=0x7fef13c02a80
The result: X=0.100000000000, Y=0.200000000000, length=1
它不会崩溃。我没有在Valgrind 下运行它。它将报告分配的内存泄漏。
您的类型名称ArrayOfStructures 对于其中没有数组的类型似乎非常不合适。我希望它会被命名为Point。我假设您的 Config 结构已针对此问题最小化(如果是,谢谢)。如果不是,那么持有指向另一个结构的单个指针的结构不会给您带来任何好处。它只会减慢您对数据的访问速度——远远超过使用uint_fast64_t 而不是size_t 带来的任何好处。您需要注意为Config 结构分配内存;目前,您不能简单地释放 Config 及其子结构中的所有内容。
使用指向结构的指针数组
这与上一个代码非常相似,但您需要一组额外的内存分配。我已经把它变成了一个循环,因为使用这种设计的唯一原因是允许您单独分配指向的结构。否则,它只是不必要的复杂。我做了一些小的清理工作;有更多的改进可能。我添加了一个结构转储函数 dump_points(),我可以并且确实使用它来打印不同点的值。
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <inttypes.h>
typedef struct
{
double X;
double Y;
} ArrayOfStructures;
typedef struct
{
size_t length;
ArrayOfStructures **array;
} Points;
typedef struct
{
Points *points;
} Config;
static void dump_points(const char *tag, const Points *points)
{
printf("%s (%zu, %p)\n", tag, points->length, (void *)points);
for (size_t i = 0; i < points->length; i++)
printf("%zu: (%.12f, %.12f) %p\n", i, points->array[i]->X, points->array[i]->Y,
(void *)points->array[i]);
}
static
void add_new_array(Config *conf)
{
printf("conf=%p\n", (void *)conf);
printf("conf->points=%p\n", (void *)conf->points);
printf("conf->points->length=%zu\n", conf->points->length);
printf("conf->points->array=%p\n", (void *)conf->points->array);
conf->points->array = calloc(conf->points->length, sizeof(conf->points->array[0]));
for (size_t i = 0; i < conf->points->length; i++)
conf->points->array[i] = calloc(1, sizeof(conf->points->array[i][0]));
printf("conf->points->array=%p\n", (void *)conf->points->array);
printf("conf->points->array[0]=%p\n", (void *)conf->points->array[0]);
dump_points("Inside add new array", conf->points);
}
static
void another_function(Config *conf)
{
conf->points->length = 3;
add_new_array(conf);
conf->points->array[0]->X = 0.1;
conf->points->array[0]->Y = 0.2;
conf->points->array[1]->X = 1.1;
conf->points->array[1]->Y = 1.2;
conf->points->array[2]->X = 2.1;
conf->points->array[2]->Y = 2.2;
dump_points("Inside another function", conf->points);
}
static
void some_function(Config *conf)
{
// To pass the structure to another function
another_function(conf);
dump_points("Inside some function", conf->points);
}
int main(void)
{
// Stack's allocated memory
Config conf_;
Config *conf = &conf_;
memset(conf, 0x0, sizeof(Config));
// Stack's allocated memory
Points points;
memset(&points, 0x0, sizeof(Points));
conf->points = &points;
some_function(conf);
dump_points("Inside main", conf->points);
return(EXIT_SUCCESS);
}
示例输出(macOS 10.14.5 Mojave;GCC 9.1.0):
conf=0x7ffee6f6b408
conf->points=0x7ffee6f6b410
conf->points->length=3
conf->points->array=0x0
conf->points->array=0x7f9c0a402a70
conf->points->array[0]=0x7f9c0a402a90
Inside add new array (3, 0x7ffee6f6b410)
0: (0.000000000000, 0.000000000000) 0x7f9c0a402a90
1: (0.000000000000, 0.000000000000) 0x7f9c0a402aa0
2: (0.000000000000, 0.000000000000) 0x7f9c0a402ab0
Inside another function (3, 0x7ffee6f6b410)
0: (0.100000000000, 0.200000000000) 0x7f9c0a402a90
1: (1.100000000000, 1.200000000000) 0x7f9c0a402aa0
2: (2.100000000000, 2.200000000000) 0x7f9c0a402ab0
Inside some function (3, 0x7ffee6f6b410)
0: (0.100000000000, 0.200000000000) 0x7f9c0a402a90
1: (1.100000000000, 1.200000000000) 0x7f9c0a402aa0
2: (2.100000000000, 2.200000000000) 0x7f9c0a402ab0
Inside main (3, 0x7ffee6f6b410)
0: (0.100000000000, 0.200000000000) 0x7f9c0a402a90
1: (1.100000000000, 1.200000000000) 0x7f9c0a402aa0
2: (2.100000000000, 2.200000000000) 0x7f9c0a402ab0
令人欣慰的是,数据在返回函数链时并未损坏。