C 語言中的 bzero 函式

Jinku Hu 2023年10月12日
  1. C 語言中使用 bzero 函式將記憶體區域清零
  2. 在 C 語言中使用 explicit_bzero 函式將記憶體區域清零
  3. 使用 memset 函式將 C 語言中的記憶體區域清零
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);
}
作者: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

DelftStack.com 創辦人。Jinku 在機器人和汽車行業工作了8多年。他在自動測試、遠端測試及從耐久性測試中創建報告時磨練了自己的程式設計技能。他擁有電氣/ 電子工程背景,但他也擴展了自己的興趣到嵌入式電子、嵌入式程式設計以及前端和後端程式設計。

LinkedIn Facebook

相關文章 - C Memory