内存泄漏、字节对齐、数组越界
内容纲要
atoi (表示ascii to integer)是把字符串转换成整型数的一个函数,应用在计算机程序和办公软件中。 
int atoi(const char *nptr) 函数会扫描参数nptr字符串,会跳过前面的空白字符(例如空格,tab缩进)等。 
如果nptr不能转换成int 或者nptr为空字符串,那么将返回0 。

小心字节对齐方面的问题: 以及返回类型不能是引用类型,容易变成野指针。

内存对齐,在结构体中,内存往往都是4或者8 的整数倍,如果想要结构体定义成想要的内存的形式,可以进行如下操作 使用 #pragma pack(1)

#pragma pack(1)
struct dev_Info
{
    /* data */
    uint8_t ver;
    uint8_t plevel;
    uint16_t cel;  // 2字节
    uint16_t rssi; // 2 字节
    uint16_t rsrp; // 2 字节
    uint16_t rsrq; // 2 字节
    uint16_t snr;  // 2字节
};

struct sensor_Info
{
    /* data */
    uint8_t ct;
    uint16_t volt;
    uint16_t tp1;
    uint16_t tp2;
    uint16_t tp3;
    uint8_t upd[3]; // 三个字节就用数组来实现
    uint16_t stp;
    uint8_t srh;
    uint8_t way;
};

typedef struct
{
    /* data */
    struct
    {
        char imei[16];  // 这后面 有一个\0 要算进去
        char imsi[16];
        char iccid[21];
    } sim_Info;
    struct dev_Info dev;
    struct sensor_Info sensor;
} cm_info_t;
#pragma pack()

itoa( ) 与 atoi( ) 函数 以及 sscanf( )

  • 关于C中数组初始化,其数组长度不能是变量,不然编译器会报错,编译器在编译过程中不能确定开辟内存大小(哪怕你的变量是知道的,但是它是sizeof( ) 出来的 )。

    解决办法:

    char * const test = (char *)malloc(size); 使用malloc 开辟空间,记得要释放哈,

    const 也能去掉, 不过加一个const 保证指针test 不会修改它的指向

  int size = sizeof(uploadDATA);
    // char test[size] = {0}; // C中不能动态初始化 数组,也就是数组长度不能是变量
    char * const test = (char *)malloc(size);
  • 数组的拷贝

  • 值得注意的点:

    1. 使用 cm_sim_get_imsi(&imsi); 拷贝出来的字符串长度 和结构体uint8_t 的长度不同,uint8_t 长度应该为字符串拷贝的一半,因为它一次把 2 个字符 转成16进制 进行存储。
    2. 这里找到的问题,

比对

  • imsi[8] 的时候的数组情况

file

  • imsi[16] 时候

    file

大的问题点

数组越界:

  1. 结构体中,创建了3个 变量,在这边给结构体初始化的时候,内存分配的空间没给够,导致数组越界!!,离谱,造成的结果是:因为 iccid[] 数组长度没给够,使得 imsi 获取的值被 iccid 乱传值,遇到此BUG。

    file

    file

结构体数据处理,

  • 之前我考虑的是,由于 整个大结构体中 只有 imei 、 imsi 、iccid 三个变量是 字符串别的都是 基本数据类型,所以我打算把这3个变量做成 uint8_t 。所以问题就出现了。
  1. 做成 基本数据类型的时候, imei 占用15 个字符长度, 而且 基本数据类型的数组后面都有 \0, 这个问题处理起来比较棘手。
  2. 那便是 string 类型转化为 int 类型比较麻烦。特别麻烦。用 sscanf( ) 函数也不方便。

解决办法:把待传的参数做成一整个长字符串,就没这么多问题了。

TIP: 大部分时候memcpy() 比 遍历赋值好用得多

关于MN316 开发板的电压获取函数的问题,导致的结果是获取iccid 报错

  • 关注点:
    1. 通过指针来 进行结构体的数据拷贝,更简单。
    2. 使用malloc 来进行数组的动态创建。(一般数组的长度不能是变量,但是malloc 可以实现数组这个功能)
    /* 创建指针,指针指向后续需要把 整形 转化为字符串类型的第一个地址。
       通过长度来进行数据拷贝做成字符数组 */
    int uint_SIZE = sizeof(uploadDATA.dev) + sizeof(uploadDATA.sensor);
    // uint8_t toArray[29] = {0}; // 这里使用 malloc 开辟内存, 动态初始化数组,提高灵活性
    uint8_t *const toArray = (uint8_t *)malloc(uint_SIZE);  // 本质就是数组(指针常量,指针不可变,即为引用&)
    uint8_t *pStruct = &uploadDATA.dev.ver; // 创建结构体指针,
    char *const temp = (uint8_t *)malloc(uint_SIZE);
    // char temp[29] = {0};  //由于数组开辟内存的时候不能使用变量开辟
    memcpy(toArray, pStruct, uint_SIZE); //   !!通过指针进行内存的拷贝,数据大小为uint8_t 需要转化为string 的长度
    ArrayToStr(toArray, sizeof(toArray), temp);  //toArray 转化为 temp字符串
    cm_demo_printf("temp == %s \n", temp);
    cm_demo_printf("sizeof(temp) == %d \n", sizeof(temp));

(还是尽量少用char *const temp = (uint8_t *)malloc(uint_SIZE); 避免忘记释放内存而翻车)

  • 在这个项目中,我没有使用指针 构建动态数组,估计是我malloc 之后没有用memset初始化内存,导致有问题,所以我还是老老实实使用的数组来存放数据
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇