C 言語で bzero 関数を使用する

胡金庫 2023年10月12日
  1. 関数 bzero を使って C 言語のメモリ領域をゼロにする
  2. C 言語でメモリ領域をゼロにするには explicit_bzero 関数を使用する
  3. C 言語のメモリ領域をゼロにするには memset 関数を使用する
C 言語で bzero 関数を使用する

この記事では、C 言語で bzero 関数を利用する方法について複数の方法を示します。

関数 bzero を使って C 言語のメモリ領域をゼロにする

メモリ管理は、ユーザーが基本的なメモリ構造と対話して操作する必要があるため、C 言語プログラミングのコアタスクの 1つです。したがって、メモリ領域をゼロにすることは、多くのシナリオで使用される一般的な操作です。時には、動的なメモリをゼロで上書きして、ガベージ値からクリアしなければならないこともあります。時には、複数のビットマスク値を含む struct があり、そのメンバの初期化の前に明示的にゼロアウトする必要があります。この例では、後に指定されたソケットにバインドするために使用されるソケットアドレス構造体をゼロアウトするコードを示します。関数 bzero は、与えられたメモリ領域をゼロバイト(\0)で消去することができます。この関数は 2つの引数をとり、メモリ領域の開始アドレスとゼロにするバイト数を指定します。

#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);
}

C 言語のメモリ領域をゼロにするには memset 関数を使用する

memset は標準の C 言語ライブラリの一部であり、これら 3つの関数の間のほとんどのシナリオで推奨されるメソッドでもある。bzero は減価償却された関数であり、最近のコードベースでは使用すべきではません。しかし、memset の操作は explicit_bzero とは対照的にコンパイラによって最適化できます。

memset は 3つの引数を取ります。

  • メモリアドレス。
  • メモリを埋める定数バイト。
  • 上書きするバイト数。

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);
}
著者: 胡金庫
胡金庫 avatar 胡金庫 avatar

DelftStack.comの創設者です。Jinku はロボティクスと自動車産業で8年以上働いています。自動テスト、リモートサーバーからのデータ収集、耐久テストからのレポート作成が必要となったとき、彼はコーディングスキルを磨きました。彼は電気/電子工学のバックグラウンドを持っていますが、組み込みエレクトロニクス、組み込みプログラミング、フロントエンド/バックエンドプログラミングへの関心を広げています。

LinkedIn Facebook

関連記事 - C Memory