打印
[学习资料]

memset的使用

[复制链接]
57|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
小明的同学|  楼主 | 2025-6-20 19:46 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
为何要下面这样操作     
    uint8_t zero_buf[16];
    memset(zero_buf, 0, sizeof(zero_buf));难道声明一个新的数组后不是自动填充0吗?

在 C 语言中,局部数组声明后不会自动初始化为零,这是 C 语言的一个重要特性,也是内存管理的基础概念。
为什么需要显式初始化?
1. C 语言的内存管理原则
在 C 语言中:

局部变量(包括数组)存储在栈上

栈内存不会被自动初始化 - 它包含的是该内存位置上次使用后的残留值

全局变量和静态变量会被初始化为零,但局部变量不会

2. 未初始化数组的风险
如果省略 memset:
uint8_t zero_buf[16]; // 包含随机垃圾值
当将这个数组发送给 OLED 时:

每个字节都是不可预测的值(可能是 0x00 到 0xFF 之间的任意值)

OLED 会将非零值解释为"亮"的像素点

结果:屏幕上会出现随机噪点而不是清晰的空白

使用特权

评论回复
沙发
小明的同学|  楼主 | 2025-6-20 19:47 | 只看该作者
3. 性能与内存的权衡
使用 16 字节缓冲区是精心设计的平衡方案:
// 方案对比
uint8_t zero_buf[16];       // 栈空间: 16字节 → 安全
memset(zero_buf, 0, 16);    // 快速初始化

// 替代方案1: 128字节数组 → 栈溢出风险
uint8_t big_buf[128] = {0}; // 可能超出小型MCU的栈空间

// 替代方案2: 单字节写入 → 效率极低
for(int i=0; i<128; i++) {  // 128次I2C传输 × 8页 = 1024次!
    uint8_t zero = 0;
    ssd1306_data(&zero, 1);
}
优化建议


1. 静态常量优化 (推荐)
void ssd1306_clear() {
    // 静态常量 - 编译时初始化,不占额外RAM
    static const uint8_t ZERO_BLOCK[16] = {0};
   
    for(uint8_t page = 0; page < 8; page++) {
        // ...设置页地址...
        for(uint8_t col = 0; col < 8; col++) {
            // 使用常量数据块
            ssd1306_data((uint8_t*)ZERO_BLOCK, sizeof(ZERO_BLOCK));
        }
    }
}
优点:

零运行时初始化开销

不占用栈空间

可读性好

2. 汇编级优化 (极致性能)
// 使用寄存器直接清零
void ssd1306_fill_zero(uint8_t page) {
    ssd1306_cmd(0xB0 | page);
    ssd1306_cmd(0x00);
    ssd1306_cmd(0x10);
   
    uint8_t buf[17] = {0x40}; // 0x40 = 数据头
    // 编译器可能优化为块清零操作
    for(int i=1; i<17; i++) buf[i] = 0;
   
    for(uint8_t i=0; i<8; i++) {
        i2c_write(SSD1306_I2C_ADDR, buf, sizeof(buf));
    }
}



使用特权

评论回复
板凳
小明的同学|  楼主 | 2025-6-20 19:48 | 只看该作者
C 语言局部变量不会自动初始化 - 这是有意为之的设计选择

显式初始化是良好实践 - 确保可预测的行为

小缓冲区设计是优化平衡:

内存效率 (16字节 vs 128字节)

I²C传输效率 (64次 vs 1024次)

静态常量是最佳实践 - 结合了安全性和性能

在嵌入式开发中,这种显式初始化模式很常见,它确保:

确定性行为(四轴飞行器像素)

可移植性(不依赖编译器实现)

资源高效利用(小内存占用)

理解这些底层细节有助于编写更可靠、高效的嵌入式代码!

使用特权

评论回复
地板
小明的同学|  楼主 | 2025-6-20 19:50 | 只看该作者
我也是今天才关注到这个问题的,然后收集资料,整理了这个帖子,希望对大家有帮助。之前我以为新建一个数组后就自动填充0了呢。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

155

主题

1606

帖子

2

粉丝