My data has structure like the following:
typedef struct struct2 {
uint8_t num;
uint8_t action;
uint8_t id;
} struct2_t;
typedef struct struct1 {
uint8_t title;
struct2_t* content;
} struct1_t;
I assigned a memory space to a structure pointer and printed out the value.
void main(){
const uint8_t msg[5] = {
5, 4, 3, 2, 1
};
struct1_t *req = NULL;
req = (struct1_t *)msg;
printf("%d ", req->title);
printf("%d ", req->content->num);
printf("%d ", req->content->action);
printf("%d ", req->content->id);
}
The result is: 5 5 4 3 while I expected it to be 5 4 3 2?
Besides, in another place I copy the content in my buffer and do the similar thing.
void main(){
const uint8_t msg[5] = {
5, 4, 3, 2, 1
};
uint8_t *test = NULL;
test = (uint8_t*)malloc(5 + 1);
memset((test), 0x00, 5);
memcpy(test, msg , 5);
struct1_t *req = NULL;
req = (struct1_t *)test;
printf("%d ", req->title);
printf("%d ", req->content->num);
printf("%d ", req->content->action);
printf("%d \n", req->content->id);
}
But this time I can not access the struct2_t pointer
5 Segmentation fault (core dumped)
Can anyone tell me what I'm missing? Thanks for you help
答案 0 :(得分:1)
您似乎缺少的是明确了解何时将dot
(.
)运算符与结构一起使用以及何时使用arrow
(->
)运营商。
规则很简单。如果您有struct
,则可以使用.
运算符访问其成员。如果您有pointer to a struct
,则可以使用->
箭头运算符访问其成员。当您的struct
包含pointer to a struct
时,请使用其中一个。
以下示例应该明确说明并提供使用content
指针指向具有自动存储s2
的结构和存储在动态分配的内存中的结构的示例' s3& #39;
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <inttypes.h>
enum { MAXL = 128, MAXC = 512 };
typedef struct struct2 {
uint8_t num;
uint8_t action;
uint8_t id;
} struct2_t;
typedef struct struct1 {
uint8_t title;
struct2_t *content;
} struct1_t;
int main (void) {
struct2_t s2 = { 5, 4, 3 }, *s3 = NULL;
struct1_t s1 = { 2, &s2 }; /* content initialized to s2 */
/* using address of s2 as content */
printf ("\n title : %" PRIu8 "\n"
" num : %" PRIu8 "\n"
" action : %" PRIu8 "\n"
" id : %" PRIu8 "\n", s1.title,
s1.content->num, s1.content->action,
s1.content->id);
/* dynamic allocation of s3 */
if (!(s3 = calloc (1, sizeof *s3))) {
fprintf (stderr, "error: virtual memory exhausted.\n");
return 0;
}
s3->num = 8; /* assignment of values to s3 */
s3->action = 7;
s3->id = 6;
s1.content = s3; /* update content pointer to s3 */
/* using address of s3 as content */
printf ("\n title : %" PRIu8 "\n"
" num : %" PRIu8 "\n"
" action : %" PRIu8 "\n"
" id : %" PRIu8 "\n", s1.title,
s1.content->num, s1.content->action,
s1.content->id);
free (s3); /* don't forget to free all memory you allocate */
return 0;
}
示例输出
$ ./bin/structnested
title : 2
num : 5
action : 4
id : 3
title : 2
num : 8
action : 7
id : 6
查看示例并告诉我您是否有任何其他问题,或者如果我错过了您的部分问题,请告诉我。
答案 1 :(得分:0)
您永远不会初始化content
,因此您会获得未定义的行为。你需要这样做:
/* ... */
req = (struct1_t *)msg;
req->content = (struct2_t *)&msg[1];
printf("%d ", req->title);
/* ... */
Typepunning不是递归的。
答案 2 :(得分:0)
你的代码中有两个faws,首先在struct1中使用指向struct2的指针,但是你正在用数据填充struct1实例的内存,因此你的一个值被认为是一个指针。 其次,您必须考虑结构内数据的对齐。 Teh编译器根据数据类型和目标体系结构放置数据,并使用填充字节填充空格。由于32位架构通常在4字节对齐时更好地访问数据,因此编译器会将struct1(或struct1指针)移动到下一个4字节对齐的地址。所以你有代码
0xYYYYYYYY+00 struct1.title (byte0)
0xYYYYYYYY+01 padding byte0
0xYYYYYYYY+02 padding byte1
0xYYYYYYYY+03 padding byte2
0xYYYYYYYY+04 struct1.struct2*
如果你纠正指针问题:那么你有
0xYYYYYYYY+00 struct1.title (byte0)
0xYYYYYYYY+01 padding byte0
0xYYYYYYYY+02 padding byte1
0xYYYYYYYY+03 padding byte2
0xYYYYYYYY+04 struct1.struct2.num
0xYYYYYYYY+05 struct1.struct2.action ( here is no padding,as the data iself is u8)
0xYYYYYYYY+06 struct1.struct2.id( here is one paddingbyte,as the data iself is u8, but at the end of the structure).
一般来说,我建议不要以这种方式初始化srtuct,因为你必须考虑编译器的对齐逻辑,这可能有点棘手。