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