C 語言中的 bzero 函式

Jinku Hu 2023年1月30日 2021年2月28日
  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 "unistd.h"
#include "sys/un.h"
#include "sys/socket.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 "unistd.h"
#include "sys/un.h"
#include "sys/socket.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 "unistd.h"
#include "sys/un.h"
#include "sys/socket.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);
}
Author: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn

相關文章 - C Memory