C 語言中的 bzero 函式
 
本文將演示關於如何使用 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);
}
        Enjoying our tutorials? Subscribe to DelftStack on YouTube to support us in creating more high-quality video guides. Subscribe
    
作者: Jinku Hu
    
