C语言 类型转换为具有另一个结构 ptr 的结构



我的数据具有如下结构:

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;

我为结构指针分配了一个内存空间并打印出该值。

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);
}

结果是:5 5 4 3而我预计是 5 4 3 2?

此外,在另一个地方,我将内容复制到缓冲区中并执行类似操作。

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);
}

但是这次我无法访问struct2_t指针

5分段故障(核心转储)

谁能告诉我我错过了什么?谢谢你的帮助

您似乎缺少的是清楚地了解何时使用带有结构的dot.)运算符以及何时使用arrow->)运算符。

规则很简单。如果您有 struct ,则可以使用 . 运算符访问其成员。如果您有 pointer to a struct ,则可以使用 -> 箭头运算符访问其成员。当您有一个包含pointer to a structstruct时,请使用每个中的一个

下面的示例应该清楚地说明这一点,并提供使用 content 指针指向具有自动存储s2的结构和存储在动态分配的内存"s3"中的结构的示例。

#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

查看示例,如果您有任何其他问题,或者如果我错过了您问题的一部分,请告诉我。

你从不初始化content所以你会得到未定义的行为。您需要做:

/* ... */
    req = (struct1_t *)msg;
    req->content = (struct2_t *)&msg[1];
    printf("%d ", req->title);
/* ... */

类型双关不是递归的。

代码中有两个 faw,首先在 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,因为您必须考虑编译器的对齐逻辑,这可能有点棘手。

相关内容

  • 没有找到相关文章

最新更新