当我使用此代码时,我想转向如下结构数组的每个元素:
array[0]->X;
array[1]->X;
我尽力了,但是在所有情况下,我都遇到了细分错误。我在做什么错了?
请查看#if 0 #endif
之间的块#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;
void add_new_array(Config *conf)
{
printf("conf=%p\n",conf);
printf("conf->points=%p\n",conf->points);
printf("conf->points->length=%zu\n",conf->points->length);
printf("conf->points->array=%p\n",conf->points->array);
#if 0
ArrayOfStructures *temp = (ArrayOfStructures*)calloc(conf->points->length,sizeof(ArrayOfStructures));
printf("temp=%p\n",temp);
// Segmentation fault
*conf->points->array = temp;
#else
conf->points->array = (ArrayOfStructures **)calloc(conf->points->length,sizeof(ArrayOfStructures *));
#endif
printf("conf->points->array=%p\n",conf->points->array);
}
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=%zu\n",conf->points->array[0]->X,conf->points->array[0]->Y,conf->points->length);
}
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);
}
编译使用:
gcc -D_SVID_SOURCE -g -ggdb -ggdb1 -ggdb2 -ggdb3 -O0 -DDEBUG -std=c11 -Wall --pedantic arryay.c -o array
我试图找到处理双指针的答案,但是一切都很混乱。
答案 0 :(得分:1)
您似乎没有将length
初始化为有意义的值。因此,您实际上并没有分配内存,因为您在第一个参数为零的情况下调用了calloc()
。
(免责声明:我尚未测试代码,但这似乎是错误的。)
答案 1 :(得分:1)
根据comment,您已经非常接近想要的东西。
这是您的代码的改编版。主要更改是使用ArrayOfStructs *array
而不是使用指针到指针。另外,由于您决定对数据类型使用uint_fast64_t
,因此必须使用PRIuFAST64
中的<inttypes.h>
来获取正确的格式字符串。最好将其更改为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
令人欣慰的是,在将数据传递回功能链时,数据没有损坏。