memcpy関数 - メモリ領域をバイト単位でコピーする
memcpy関数は、メモリ領域をバイト単位でコピーする関数です。「string.h」をインクルードします。
#include <string.h> void *memcpy(void *buf1, const void *buf2, size_t n);
第一引数はコピー先のアドレスです。汎用ポインタ型ですので、どのポインタ型でも大丈夫です。
第二引数はコピー元のアドレスです。汎用ポインタ型ですので、どのポインタ型でも大丈夫です。
第三引数にバイトサイズを指定します。size_t型です。int32_t型までの範囲で0以上の数値であれば、まず安心です。0の指定は有効な引数で、この場合コピーは行われません。
コピー先とコピー元のデータ領域が重なっていた場合には、動作は保証されません。コピー先とコピー元のデータ領域が重なっていた場合でも正しく動作させる場合はmemmove関数を使用してください。重ならない場合は、性能が優先されるmemcpy関数を使いましょう。
文字列をコピーする
memcpy関数で文字列をコピーするサンプルです。strlen関数で、文字列の長さを取得、calloc関数で、メモリ領域を確保、その領域にmemcpy関数でコピーという処理を行っています。コピー先の変数にconst修飾子がついていると、コピーできないので、const修飾子がつかない一時的な文字列にコピーしています。
#include <stddef.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
int main(void) {
// 文字列
const char* message = "Hello";
// 文字列の長さ
int32_t message_length = strlen(message);
// メモリ領域を確保
char* new_message_tmp = calloc(sizeof(char), message_length + 1);
// memcpy関数で一時的な文字列にコピー
memcpy(new_message_tmp, message, message_length);
// 新しい文字列に代入(const修飾子をつけたいので)
const char* new_message = new_message_tmp;
new_message_tmp = NULL;
printf("%s\n", new_message);
}
出力結果です。
Hello
符号あり32bit整数の配列をコピーする
memcpy関数でint32_t - 符号あり32bit整数の配列をコピーするサンプルです。calloc関数で、メモリ領域を確保、その領域にmemcpy関数でコピーという処理を行っています。コピーする長さは「要素の型のサイズ × 配列の長さ」になることに注意してください。for文で、配列の要素を出力しています。
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
int main(void) {
// 配列
int32_t nums_length = 3;
int32_t nums[] = {3, 5, 7};
// メモリ領域を確保
int32_t* new_nums = calloc(sizeof(int32_t), nums_length);
// memcpy関数でint32_t型の配列をコピー
memcpy(new_nums, nums, sizeof(int32_t) * nums_length);
for (int32_t i = 0; i < nums_length; i++) {
printf("nums[%d]: %d\n", i, new_nums[i]);
}
}
出力結果です。
nums[0]: 3 nums[1]: 5 nums[2]: 7
C言語ゼミ


