当前位置:首页 > 技术 > 正文内容

深入理解C语言中的memset函数

访客 技术 2026年7月15日 1

memset函数是C标准库中用于内存块初始化的基础工具,其原型为 extern void *memset(void *buffer, int c, size_t count)。参数含义如下:buffer 指向要操作的内存区域,c 是要设定的字节值(会被转换为无符号字符),count 指定处理的字节数。

常见应用场景

1. 数组清零:在网络编程中常用于清空缓冲区,例如 memset(buffer, 0, sizeof(buffer))

2. 字符串初始化:将字符数组设为零或空格,如 char a[100]; memset(a, '\0', sizeof(a));

3. 结构体清零:避免逐字段赋值的繁琐。假设有以下结构体定义:

struct sample_struct {  
    char csName[16];  
    int iSeq;  
    int iType;  
};

若变量为 struct sample_struct stTest;,传统方法需三次赋值,而使用 memset 只需一行:memset(&stTest, 0, sizeof(struct sample_struct));。对于数组 struct sample_struct TEST[10];,则用 memset(TEST, 0, sizeof(struct sample_struct) * 10);

工作原理

memset 以字节为单位对内存进行填充,核心实现大致如下:

#include <mem.h>  
void* memset(void* s, int c, size_t n) {  
    unsigned char* p = (unsigned char*) s;  
    while (n-- > 0) {  
        *p++ = (unsigned char) c;  
    }  
    return s;  
}

误用与陷阱

1. 参数顺序混淆:正确写法是 memset(a, 0, 20),而非 memset(a, 20, 0)

2. 不必要的初始化:例如在即将被覆盖的内存上调用 memset 是多余的:

char buffer[20];  
memset(buffer, 0, sizeof(buffer)); // 无意义  
strcpy(buffer, "123");

3. 对非字符类型使用错误:memset 按字节赋值,对 int 等类型会导致意外结果。例如:

int a[5];  
memset(a, 1, 5 * sizeof(int));  
// 每个 int 元素实际变成 0x01010101(十进制的 16843009)

因为每个 int 占 4 字节,赋值为 1 字节的 0x01,组合后即上述值。

与其他内存函数的对比

  • memcpy:用于内存块拷贝,可处理任意数据类型,需指定字节数。例如 memcpy(b, a, sizeof(b));
  • strcpy:仅用于字符串拷贝,遇到 '\0' 停止。例如 strcpy(a, b); 可能因源字符串过长导致缓冲区溢出。

常见问题解答

Q: 为什么必须清零内存?

未初始化的内存可能含有随机值(野值),导致程序行为不可预测。例如测试字符数组时,未清零会出现乱码。

Q: 能否用 memset 直接将 int 数组所有元素设为 1?

不能。memset 按字节操作,memset(a, 1, 5 * sizeof(int)) 实际上将每个 int 赋值为 0x01010101。若需初始化,可改用 for 循环或 std::fill(C++)。

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。