typedef struct {
int num;
char arr[64];
} A;
typedef struct {
int num;
char arr[];
} B;
我声明了A* a;
,然后将一些数据放入其中。现在,我要将其投射到B*
。
A* a;
a->num = 1;
strcpy(a->arr, "Hi");
B* b = (B*)a;
这是对的吗?
有时(并非总是)出现细分错误,我想知道这是否可能是问题的原因。
即使在投射后我没有尝试访问char arr[]
,我仍然遇到了细分错误。
答案 0 :(得分:3)
这定义了一个指针变量
A* a;
它没有指向任何东西,指针未初始化。
这将访问它指向的任何内容
a->num = 1;
strcpy(a->arr, "Hi");
没有事先分配任何内容给指针(例如,使用malloc()
),这是因为它调用的未定义行为可能会导致段错误。
答案 1 :(得分:1)
这是Yunnosch's answer的附录,可正确识别问题。假设您正确执行了操作,要么只写
A a;
,当您在函数中声明该对象时,它会为您提供自动存储期限的对象,或者您可以像这样动态分配A
的实例:
A *a = malloc(sizeof *a);
if (!a) return -1; // or whatever else to do in case of allocation error
然后,接下来的事情就是你的演员表:
B* b = (B*)a;
这是不正确的,类型A
和B
不兼容。在这里,它可能在实践中可行,因为struct
成员是兼容的,但是请注意,由于允许编译器假设a
和{{1} }指向不同的对象,因为它们的类型不兼容。有关更多信息,请阅读通常称为 strict别名规则的主题。
您还应该知道,不完整的数组类型(无大小)仅允许作为b
的最后一个成员。像您这样的定义:
struct
成员typedef struct {
int num;
char arr[];
} B;
的大小是允许的,但是正确分配它是您的责任。 arr
(B
)的大小不包含此成员。所以如果你只是写
sizeof(B)
您不能在B b;
中存储任何内容,它的大小为b.arr
。最后一个成员称为 flexible array成员,并且只能与动态分配一起正确使用,并手动添加大小,如下所示:
0
这为您提供了一个实例B *b = malloc(sizeof *b + 64);
,其实例大小为*b
。arr
如果数组的类型不是char
,则必须手动乘以成员类型的大小-char
不必要,因为sizeof(char)
的定义是1
。因此,如果您将数组的类型更改为其他类型,例如int
,您可以编写此代码以分配64个元素:
B *b = malloc(sizeof *b + 64 * sizeof *(b->arr));
答案 2 :(得分:0)
您似乎在混淆两个不同的主题。在C99 / C11中,char arr[];
作为结构的最后一个成员是 Flexible Array Member (FAM),它允许您为结构本身和N
个元素数量分配用于灵活的数组。但是,您必须为其分配存储空间。 FAM的好处是在通常需要两个分配的情况下允许一次分配和一次免费。 (在C89中,类似的实现被命名为 struct hack ,但略有不同)。
例如,B *b = malloc (sizeof *b + 64 * sizeof *b->arr);
将为b
plus 分配64个字符的存储空间,用于b->arr
。然后,您可以使用正确的a
和b
语法将'.'
的成员复制到'->'
。
一个简短的例子可以说明:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NCHAR 64 /* if you need a constant, #define one (or more) */
typedef struct {
int num;
char arr[NCHAR];
} A;
typedef struct {
int num;
char arr[]; /* flexible array member */
} B;
int main (void) {
A a = { 1, "Hi" };
B *b = malloc (sizeof *b + NCHAR * sizeof *b->arr);
if (!b) {
perror ("malloc-b");
return 1;
}
b->num = a.num;
strcpy (b->arr, a.arr);
printf ("b->num: %d\nb->arr: %s\n", b->num, b->arr);
free (b);
return 0;
}
使用/输出示例
$ ./bin/struct_fam
b->num: 1
b->arr: Hi
仔细检查一下,如果有帮助,请告诉我。如果您有其他问题,也请告诉我。您不清楚混乱的确切位置。