C 语言 memset2025年3月17日 | 阅读 7 分钟 C 语言是一种严格编译型编程语言,它是当今编程世界中所有其他语言的基础。换句话说,用 C 语言编写的程序只有在编译后才能运行。C 语言受限于某些参数或函数,但包含一些具有特定用途的不同函数。在本文中,您将了解 C 语言中的 memset() 以及与之相关的其他因素和用例。 什么是 memset()?memset 函数(“内存设置器”)是 C 语言中的一个标准库函数,用于将内存块以语义方式设置为指定值或用指定值填充。 例如,假设您有一个包含 8 个字符的数组,在声明该数组时会占用 8 字节内存,您的计算机会在系统中堆上分配 8 字节内存。这种内存分配不是随机的。随机化仅在地址空间布局随机化等进程发生时出于示例目的,或者在 0x00 到 0x07 的范围内进行十六进制地址分配。假设您声明了一个 8 个字符的数组,如下所示。 ![]() 最初,您完全不知道由数组占用的这块内存的内容,因为您没有初始化数组。虽然它可能什么都没有,但可能是您在之前的程序中使用过的旧值,或者内存中的块可能是未定义的。 通常,为了遵循 C 语言的良好实践,最好能完全控制程序中使用的任何内存。因此,您不应该将这 8 字节内存留空,而应该始终用已知值或指定值以及空字节 (\0) 来设置或填充内存。这样,您就可以确保对您定义的数组所占用的内存块进行完全控制。请参阅下图以获得关于所讨论内容的视觉效果。 ![]() 换句话说,您想要做的就是 memset() 函数块。memset() 函数接受以下参数。该函数接受三个参数:指向内存块的指针、一个整数以及一个 size_t,size_t 是一个无符号整数变量,用于保存数组的任何索引。 第一个参数表示 void 类型的指针,因为内存块最初是空的或即将被填充。void 类型表示该指针可以引用内存,而不考虑其类型。 第二个参数是要填充指针分配的整数。请注意,此参数作为整数参数接收,然后在需要填充内存时将其转换为字符。此转换可确保函数仅保留整数参数所需的 8 位。否则,它可能会占用比所需更多的内存。 第三个参数表示要填充的内存块的给定大小。当指针引用要填充的内存位置时,它不会告诉您应该填充多少内存。因此,传递此参数的主要目的是确保大小正确且为正,以免内存分配出现内存泄漏。 memset() 的返回值memset() 的默认返回值为 void *(无返回类型的指针)。如果您期望获得传递给这些函数的对象,则可能从 memset() 处一无所获。您可能只会在函数返回并返回调用 memset 函数时传递的相同内存地址的指针后才获得一些输出。 如何使用 memset()?要在您的程序中使用 memset(),您需要做的第一件事就是包含 string 头文件,如下所示。 一旦在程序中包含 C 语言的 string 库,您就不需要其他任何东西了。您可以直接访问 memset 函数。为了使其更清晰易懂,请考虑以下代码片段,其中包含另外两个库,如 <stdio.h> 和 <stdlib.h>(用于 exit 和 printf)。 何时使用 memset()?如前所述,在 C 语言编程中,在分配内存和初始化内存时,严格控制和维护内存始终是最佳实践。如果您不立即初始化,则可能会使用 strcpy 等其他专用函数。strcpy 的正确使用涉及一种新的内存块分配方法,在该方法中,在实际使用字符串的副本之前将其保留。由于它没有被初始化,因此在使用 strcpy 之前可能需要先声明它。在这种情况下,memset() 非常适合填充块或在初始时将其清空。请考虑下面的示例,以了解为什么使用 memset()。 总而言之,在处理 C 语言和内存分配方法时,memset() 是一个非常值得考虑的工具。简单来说,如果不能初始化,就 memset()。 memset() 的应用到目前为止,您已经看到了针对特定 memset() 实例的所有相关示例和用例。但是,为了更好地理解,您需要查看将在 memset() 的应用程序中讨论的多个示例。请看下面描述其应用程序的示例。 示例 1 输出 a = Hello from JournalDev Filling the first five characters a with 'H' using memset After memset, a = HHHHH from JournalDev 从前面以及这个例子中可以清楚地看出 memset() 如何处理初始化。在上面的代码中,您可以看到 memset() 如何与定义字符数组或字符串大小的变量一起工作。使用 memset() 函数后,您可以看到给定的字符串中有五个重复的字符 H。 示例 2 输出 a = Hello from JournalDev Filling the last five characters a with 'H' using memset After memset, a = Hello from JournHHHHH 这个例子与前一个例子类似,但有一个引人注目的特点。理解同一程序的变体以及 memset() 的不同用法技巧非常重要。在上面的例子中,您可以看到只填充了偏移位置。在此示例中,唯一的区别是最后五个字符用 H 填充,因为您可以看到内存位置或地址初始化已经完成。 memset() 与 calloc() 与手动迭代有时,您可以选择使用 memset() 将数组初始化为零。通常,其他函数(如手动迭代或使用 calloc() 函数)存在一些性能问题。还有一些速度问题和内存分配技术很难理解和实现。要了解 memset() 如何解决这些问题,请参阅下面的示例代码,了解为什么使用 memset() 有益,以及如何使用 <time.h> 头文件在 Linux 机器上运行 memset() 和 calloc()。 输出 Time for memset() = 0.000002 seconds Time for calloc() = 0.000005 seconds Time for naive iteration = 0.000006 seconds 在上面的例子中,您可以轻松地观察到并理解,memset() 的速度是手动迭代和 calloc() 的三倍。它的速度之所以如此之快,是因为它已经针对 C 编译器提供的体系结构进行了优化,速度会自动提高。 结论俗话说,“当你不初始化时,就 memset()”。这句谚语通常谈论 memset() 相对于 calloc() 或手动迭代等其他方法的优势。在本文中,您了解了在数组空间空闲或未使用时如何处理此类初始化问题。您在本文中找到的问题和解决方案告诉您,在使用 C 语言进行内存分配时,memset() 可以是一个重要的方面。 下一主题C 语言中的 ASCII 表 |
我们请求您订阅我们的新闻通讯以获取最新更新。