OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4282|回复: 19

C语言结构体指针内存

[复制链接]

11

主题

61

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
202
金钱
202
注册时间
2015-11-19
在线时间
31 小时
发表于 2016-10-20 18:15:52 | 显示全部楼层 |阅读模式
本帖最后由 453044814@qq.com 于 2016-10-23 11:36 编辑

#pragma pack(1)
typedef struct{
uint8_t     a;   
uint8_t      b;
uint16_t    c;
uint8_t      *d;
}_msg;
#pragma pack()


uint8_t buffer[64];
void test(uint8_t *data)
{
   _msg  *msg = (_msg*) buffer;//相当于给msg分配了64字节    ①
  msg->a = 1;
  msg->b = 2;//没有①这里就开始错了
  msg->c = 3;
// msg->d[0] = data[0];//这里没错,应该是用了*d的空间
//  msg->d[1] = data[1];//运行错误,编译器只给*d分配了一个u8,这里会有问题。也就是说①处给结构体指针分配了内存,但是结构体内的指针并没有。
  buffer[4+0] = data[0];//可以达到上面两行的效果,这样处理需要引入3这个参数,虽然没问题,但总感觉不爽。
  buffer[4+1] = data[1];
}

坑坑,C是越用问题越多.
得找本书在看看了。

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

9

主题

538

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3371
金钱
3371
注册时间
2015-1-7
在线时间
794 小时
发表于 2016-10-20 20:58:54 | 显示全部楼层
本帖最后由 ianhom 于 2016-10-20 21:12 编辑

d是指针,d[x]不在buffer的64字节里,如果buffer里全是0,那msg->d为0,那msg->d[0] = data[0];就会出错。msg->d[0]和buffer[4+0]不是同一个内存
pack1.png
回复 支持 1 反对 0

使用道具 举报

30

主题

1170

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1993
金钱
1993
注册时间
2016-2-16
在线时间
527 小时
发表于 2016-10-20 19:39:29 | 显示全部楼层
不知道你说的什么
回复 支持 反对

使用道具 举报

2

主题

1446

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
2245
金钱
2245
注册时间
2010-12-16
在线时间
202 小时
发表于 2016-10-20 20:01:19 | 显示全部楼层
没有 1 的话 , msg->a = 1 这句也是非法的 , 只是走运不报错而已 .

你想要的是这个写法 , 但 keil 暂时不支持 .
typedef struct{
uint8_t     a;   
uint8_t      b;
uint16_t    c;
uint8_t      d[0];
}_msg;
技术讨论请发帖 , 需要我回复请点左下的 < 回复 > 让系统通知我 . 本人不通过其他方式返回任何参数.
回复 支持 反对

使用道具 举报

11

主题

1044

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3720
金钱
3720
注册时间
2011-5-23
在线时间
2012 小时
发表于 2016-10-21 09:46:15 | 显示全部楼层
本帖最后由 aozima 于 2016-10-21 09:49 编辑

d是个野指针,自己学艺不精怪C语言有坑。
RT-Thread RTOS 音频,WIFI,蓝牙
回复 支持 反对

使用道具 举报

11

主题

1044

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3720
金钱
3720
注册时间
2011-5-23
在线时间
2012 小时
发表于 2016-10-21 09:47:51 | 显示全部楼层
buffer[3+0] = data[0];

从你写的这句来看,也许你需要的是[mw_shl_code=c,true]#pragma pack(1)
typedef struct{
uint8_t     a;   
uint8_t      b;
uint16_t    c;
uint8_t      d[0];
}_msg;
#pragma pack()[/mw_shl_code]
但大部分编译器不支持0数组,或需要打开某些增强选项。

RT-Thread RTOS 音频,WIFI,蓝牙
回复 支持 反对

使用道具 举报

7

主题

90

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
325
金钱
325
注册时间
2016-10-21
在线时间
43 小时
发表于 2016-10-21 14:30:33 | 显示全部楼层
楼主是不是要这个
[mw_shl_code=applescript,true]#pragma pack(1)
typedef struct{
uint8_t     a;   
uint8_t      b;
uint16_t    c;
uint8_t      d[2];
}_msg;
#pragma pack()[/mw_shl_code]

回复 支持 反对

使用道具 举报

11

主题

61

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
202
金钱
202
注册时间
2015-11-19
在线时间
31 小时
 楼主| 发表于 2016-10-23 11:33:48 | 显示全部楼层
本帖最后由 453044814@qq.com 于 2016-10-23 11:42 编辑
ianhom 发表于 2016-10-20 20:58
d是指针,d[x]不在buffer的64字节里,如果buffer里全是0,那msg->d为0,那msg->d[0] = data[0];就会出错。m ...

我的目的就是*d 指向 buffer[4]。有什么好的方法
现在biffer[4]里面保存的是d的地址。
回复 支持 反对

使用道具 举报

11

主题

61

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
202
金钱
202
注册时间
2015-11-19
在线时间
31 小时
 楼主| 发表于 2016-10-23 11:35:15 | 显示全部楼层
ldskendy 发表于 2016-10-21 14:30
楼主是不是要这个
[mw_shl_code=applescript,true]#pragma pack(1)
typedef struct{

数组d的大小是不确定的。
回复 支持 反对

使用道具 举报

9

主题

68

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
323
金钱
323
注册时间
2016-9-1
在线时间
78 小时
发表于 2016-10-24 11:13:41 | 显示全部楼层
最近也有碰到这问题  楼主解决了吗
回复 支持 反对

使用道具 举报

9

主题

68

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
323
金钱
323
注册时间
2016-9-1
在线时间
78 小时
发表于 2016-10-24 11:18:09 | 显示全部楼层
楼主① 那句给msg分配了64字节,这样不是给*d分配了32个字节?减去前面a b c 所占用的空间
回复 支持 反对

使用道具 举报

49

主题

341

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
5265
金钱
5265
注册时间
2012-8-25
在线时间
1025 小时
发表于 2016-10-24 11:35:56 | 显示全部楼层
_msg  *msg = (_msg*) buffer;//相当于给msg分配了64字节    ① *****赋值正确

// msg->d[0] = data[0];//这里没错,应该是用了*d的空间      ******这里msg->d仍然是一个指针,但是并没有赋值,因此你的地址是随机的
用 *msg->d 引用逆可以看出来  相当于你定义了 uint8_t *data_p  data_p 没有赋值你就直接用 *data_p 了
回复 支持 反对

使用道具 举报

7

主题

90

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
325
金钱
325
注册时间
2016-10-21
在线时间
43 小时
发表于 2016-10-24 14:30:18 | 显示全部楼层
453044814@qq.co 发表于 2016-10-23 11:35
数组d的大小是不确定的。

#pragma pack(1)
typedef struct{
uint8_t     a;   
uint8_t      b;
uint16_t    c;
uint8_t      * d=(uint8_t*)0;
}_msg;

uint8_t buffer[64];
void test(uint8_t *data)
{
   _msg  msgdata;
  _msg *msg;
  msg = &msgdata;
  msg->d=buffer;
  
  msg->a = 1;
  msg->b = 2;//没有①这里就开始错了
  msg->c = 3;
msg->d[0] = data[0];//这里没错,应该是用了*d的空间
  msg->d[1] = data[1];//运行错误,编译器只给*d分配了一个u8,这里会有问题。也就是说①处给结构体指针分配了内存,但是结构体内的指针并没有。
  buffer[4+0] = data[0];//可以达到上面两行的效果,这样处理需要引入3这个参数,虽然没问题,但总感觉不爽。
  buffer[4+1] = data[1];
}
回复 支持 反对

使用道具 举报

11

主题

61

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
202
金钱
202
注册时间
2015-11-19
在线时间
31 小时
 楼主| 发表于 2016-10-27 21:00:53 | 显示全部楼层
本帖最后由 453044814@qq.com 于 2016-10-27 21:10 编辑
ldskendy 发表于 2016-10-24 14:30
#pragma pack(1)
typedef struct{
uint8_t     a;   

回复 支持 反对

使用道具 举报

11

主题

61

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
202
金钱
202
注册时间
2015-11-19
在线时间
31 小时
 楼主| 发表于 2016-10-27 21:19:31 | 显示全部楼层
#pragma pack(1)
typedef struct{
uint8_t     a;   
uint8_t      b;
uint16_t    c;uint8_t     length;//记录d中有效数据的长度
uint8_t      d[60];
}_msg;
#pragma pack()
uint8_t buffer[64];

如上,在处理d时候就不会把无效数据处理了。



回复 支持 反对

使用道具 举报

11

主题

61

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
202
金钱
202
注册时间
2015-11-19
在线时间
31 小时
 楼主| 发表于 2016-10-27 21:51:50 | 显示全部楼层
#include "sys.h"       
#include "delay.h"
/************************************************
ALIENTEK精英STM32开发板实验2
蜂鸣器实验      
技术支持:www.openedv.com
淘宝店铺:http://eboard.taobao.com
关注微信公众平台微信号:"正点原子",免费获取STM32资料。
广州市星翼电子科技有限公司  
作者:正点原子 @ALIENTEK
************************************************/
uint8_t buffer[64];

#pragma pack(1)
typedef struct{
uint8_t     a;   
uint8_t     b;
uint16_t    d_type;
uint8_t     d[60];
}_msg;
#pragma pack()

#pragma pack(1)
typedef struct{
uint8_t     a1;   
uint16_t    b1;

}_type1;
#pragma pack()

#pragma pack(1)
typedef struct{
uint16_t    a2;   
uint8_t     b2;

}_type2;
#pragma pack()

void type1_process(uint8_t *data)
{
        _type1        *msg = (_type1*)data;
        uint8_t                        parameter1;
        uint16_t                parameter2;
        parameter1 = msg->a1;
        parameter2 = msg->b1;
        parameter1 = parameter1;
        parameter2 = parameter2;
}

void type2_process(uint8_t *data)
{
        _type2        *msg = (_type2*)data;
        uint8_t                        parameter1;
        uint16_t                parameter2;
        parameter1 = msg->a2;
        parameter2 = msg->b2;
       
        parameter1 = parameter1;
        parameter2 = parameter2;
}
void revice_data(uint8_t *data )
{

        _msg  *msg = (_msg*)data;
        switch(msg->d_type)
        {
                case 1:type1_process(msg->d);break;
                case 2:type2_process(msg->d);break;
                default:break;
        }

}



int main(void)
{
         
        delay_init();                     //延时函数初始化          

        buffer[0] = 0;
        buffer[1] = 2;
        buffer[2] = 1;
        buffer[3] = 0;
        buffer[4] = 6;
        buffer[5] = 7;
        buffer[6] = 8;
        revice_data(buffer);
       
        buffer[0] = 0;
        buffer[1] = 2;
        buffer[2] = 2;
        buffer[3] = 0;
        buffer[4] = 6;
        buffer[5] = 7;
        buffer[6] = 8;
        revice_data(buffer);
        while(1);

}

这段代码表达了我想要的效果。

回复 支持 反对

使用道具 举报

11

主题

61

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
202
金钱
202
注册时间
2015-11-19
在线时间
31 小时
 楼主| 发表于 2016-10-27 21:54:04 | 显示全部楼层
留个思考题
两个type_process  中的 parameter各是多少哈哈哈哈哈哈
回复 支持 反对

使用道具 举报

11

主题

61

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
202
金钱
202
注册时间
2015-11-19
在线时间
31 小时
 楼主| 发表于 2016-10-27 21:56:22 | 显示全部楼层
不是熟手,不建议这么用,还是老实用全局数组,免得出问题哈哈哈
回复 支持 反对

使用道具 举报

11

主题

61

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
202
金钱
202
注册时间
2015-11-19
在线时间
31 小时
 楼主| 发表于 2016-10-27 21:59:12 | 显示全部楼层
shihantu 发表于 2016-10-20 20:01
没有 1 的话 , msg->a = 1 这句也是非法的 , 只是走运不报错而已 .

你想要的是这个写法 , 但 keil 暂时 ...

d  的地址紧跟c是吧
回复 支持 反对

使用道具 举报

2

主题

1446

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
2245
金钱
2245
注册时间
2010-12-16
在线时间
202 小时
发表于 2016-10-27 22:19:53 | 显示全部楼层
搜索 < 零长度数组 > .
技术讨论请发帖 , 需要我回复请点左下的 < 回复 > 让系统通知我 . 本人不通过其他方式返回任何参数.
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-24 11:45

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表