C 语言中的 bzero 函数
Jinku Hu
2023年10月12日
本文将演示关于如何使用 C 语言中的 bzero
函数的多种方法。
C 语言中使用 bzero
函数将内存区域清零
内存管理是 C 语言编程的核心任务之一,因为用户需要与基本的内存结构进行交互,并对其进行操作。因此,将内存区域清零是很多场景下常用的操作。有时,动态内存要用清零来清除它的垃圾值。有时,有一些包含多个位掩码值的 struct
,需要在其成员初始化前显式清零。在这个例子中,我们演示了将套接字地址结构清零的代码,该结构后来被用来绑定到给定的套接字。bzero
函数可以用来清除给定内存区域的零字节(\0
)。它需要两个参数,内存区域的起始地址和需要清零的字节数。
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "sys/socket.h"
#include "sys/un.h"
#include "unistd.h"
const char *SOCKNAME = "/tmp/mysocket";
int main(int argc, char *argv[]) {
int sfd;
struct sockaddr_un addr;
sfd = socket(AF_UNIX, SOCK_STREAM, 0);
if (sfd == -1) {
perror("socket");
exit(EXIT_FAILURE);
}
bzero(&addr, sizeof(struct sockaddr_un));
addr.sun_family = AF_UNIX;
strncpy(addr.sun_path, SOCKNAME, sizeof(addr.sun_path) - 1);
if (bind(sfd, (struct sockaddr *)&addr, sizeof(struct sockaddr_un)) == -1) {
perror("bind");
exit(EXIT_FAILURE);
}
if (close(sfd) == -1) {
perror("close");
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
在 C 语言中使用 explicit_bzero
函数将内存区域清零
另一种用零覆盖内存区域的方法是使用 explicit_bzero
函数。与 bzero
函数相反,explicit_bzero
保证内存区域被覆盖,即使编译器优化推断该函数是不必要的。注意,这个函数是 C 语言的非标准扩展,可能不被某些编译器所包含。
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "sys/socket.h"
#include "sys/un.h"
#include "unistd.h"
const char *SOCKNAME = "/tmp/mysocket";
int main(int argc, char *argv[]) {
int sfd;
struct sockaddr_un addr;
sfd = socket(AF_UNIX, SOCK_STREAM, 0);
if (sfd == -1) {
perror("socket");
exit(EXIT_FAILURE);
}
explicit_bzero(&addr, sizeof(struct sockaddr_un));
addr.sun_family = AF_UNIX;
strncpy(addr.sun_path, SOCKNAME, sizeof(addr.sun_path) - 1);
if (bind(sfd, (struct sockaddr *)&addr, sizeof(struct sockaddr_un)) == -1) {
perror("bind");
exit(EXIT_FAILURE);
}
if (close(sfd) == -1) {
perror("close");
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
使用 memset
函数将 C 语言中的内存区域清零
memset
是标准 C 库的一部分,也是这三个函数之间大多数情况下的推荐方法。bzero
是被贬低的函数,不应该在现代代码库中使用。虽然,与 explicit_bzero
相反,memset
操作可以由编译器优化。
memset
需要三个参数。
- 内存地址。
- 常量字节,用于填充内存。
- 要覆盖的字节数。
memset
返回一个指向内存区域的指针,可以在链式函数调用中使用。
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "sys/socket.h"
#include "sys/un.h"
#include "unistd.h"
const char *SOCKNAME = "/tmp/mysocket4";
int main(int argc, char *argv[]) {
int sfd;
struct sockaddr_un addr;
sfd = socket(AF_UNIX, SOCK_STREAM, 0);
if (sfd == -1) {
perror("socket");
exit(EXIT_FAILURE);
}
memset(&addr, 0, sizeof(struct sockaddr_un));
addr.sun_family = AF_UNIX;
strncpy(addr.sun_path, SOCKNAME, sizeof(addr.sun_path) - 1);
if (bind(sfd, (struct sockaddr *)&addr, sizeof(struct sockaddr_un)) == -1) {
perror("bind");
exit(EXIT_FAILURE);
}
if (close(sfd) == -1) {
perror("close");
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
作者: Jinku Hu