--- [PR] 当サイトはアフィリエイト広告による収益を得ています。---

【C言語】文字列のコピー strcpy sprintf の注意点

プログラミング
この記事は約8分で読めます。

プログラムにおいて、メモリを操作するための関数というものはC言語でもたくさん用意がされています。

メモリコピーができる関数

C言語において、メモリコピーができる代表的な関数として、以下が用意されています。

●指定されたサイズ分、メモリをコピーする

#include <string.h>

void *memcpy(void *dest, const void *src, size_t n);

(src のデータメモリを dest へ nバイト分コピーする)

●こちらも同じく、指定されたサイズ分のメモリをコピーする

#include <string.h>

char *strncpy(char *dest, const char *src, size_t n);

(src のデータメモリを dest へ nバイト分コピーする)

●同じようにメモリをコピーする関数で、サイズを指定しないものもあります。

#include <string.h>

char *strcpy(char *dest, const char *src);

この関数の場合、「src のデータメモリを dest へコピーする」ですが、サイズの指定はありません。

文字列を正しく扱おう

strcpyのようなコピーするサイズが指定できない場合、srcからdestへ、どれだけのサイズのデータがコピーされるのか?というと、

src で「NULL(\0)」が検出されるまで、1バイトずつ dest へコピーを続ける

という条件になります。

こういった時、src のメモリは事前にコピーしたいデータの末尾にNULL(\0)をセットしておかないと、どこまでもコピーを続けてしまい、

しまいには destの全データエリアを超えてコピーされ続けます。

◆間違いのケース

#include <string.h>

char src[5] = {'H', 'E', 'L', 'L', 'O'};
char dest[5] = {0,};         //5バイトの配列を\0埋めして初期化しておいただけ

strcpy(dest, src);

このようなコードを記述した場合の動きは下記のようになる。

この結果何が起きるのかというと、メモリオーバーフロー と呼ばれる現象で、大抵のプログラムは意図した動きではなくなり、上図でいう「変数 x」と「変数 q」には全く関係ない値がコピーされてしまい、最終的にプログラムは演算がおかしくなり、暴走します。

これが文字列操作でよくある問題です。

◆良いケース

srcを文字列としてコピーしたい時には、データの末尾に必ずNULL(\0)を入れてあげよう。

そのために、NULL(\0)をセットするためのサイズも1バイト多く確保しておくこと。

(例1)

#include <string.h>

char src[6] = {'H', 'E', 'L', 'L', 'O', '\0'};
char dest[5] = {0,};         //5バイトの配列を\0埋めして初期化しておいただけ

strcpy(dest, src);

(例2)memset()、memcpy()関数で src のデータを整えることもできる

#include <string.h>

char src[6];
char dest[5];

memset(src, 0x00, sizeof(src));    //6バイトの配列を\0埋めして初期化しておいただけ
memcpy(src, "HELLO", 5);           //srcに「HELLO」と5バイト格納する

memset(dest, 0x00, sizeof(dest));  //5バイトの配列を\0埋めして初期化しておいただけ

strcpy(dest, src);

この処理のイメージは、こうなる。

\0 の前までしかコピーしないので、元々他の場所で割り当てられていた変数x、変数qにも全く影響せずメモリコピーできます。

文字列コピー以外には標準出力関数でも同じ条件

これらの話は、標準出力関数である「printf()」や「sprintf()」でも関係します。

printf()、sprintf() は、文字列を「%s」と指定して出力することが多いと思います。

この「%s」も同じで、NULL(\0)までを読み込みながら出力するので、いつまでもNULL(\0)が存在しないメモリを出力しようとすると、破綻します。

このように、文字列を操作する際には、プログラムが暴走しないよう、NULL(\0)を上手に利用しましょう。


C言語の基礎をイメージしながら勉強できます


ITエンジニアに特化した転職支援サービス【Next Career(ネクストキャリア)】

  「エンジニアとしての経験は積んだもののそろそろ転職したほうが良いかな…」
  「これからエンジニアとして働いてみたいな…」
と考えている方!

Next Careerは、長期的なキャリア形成やキャリアプラン、転職サポートが厚く
入社後1年間はキャリアアドバイザーが相談に乗ります。

今後のキャリアアップに悩んでいる方は、ネクストキャリアで相談してみてはいかがでしょうか。

詳細はこちらから↓↓↓

中途採用向け

未経験者向け

コメント

タイトルとURLをコピーしました