Cプログラミング
 Computer >> コンピューター >  >> プログラミング >> Cプログラミング

C言語の構造体メンバー配列で自動的に行われるディープコピーの仕組み

構造体(struct)を使用すると、ユーザー定義のデータ型を作成できます。構造体のメンバーには、int や char といった基本データ型だけでなく、静的に確保されたメモリを持つ配列も含めることができます。

ある構造体変数を別の構造体変数に代入すると、通常は「シャローコピー(浅いコピー)」が行われます。しかし、ここには重要な例外があります。構造体のメンバーが配列である場合、コンパイラは自動的にディープコピー(深いコピー)を実行します。以下のサンプルコードで、この挙動を確認してみましょう。

サンプルコード

#include <stdio.h>
#include <string.h>

typedef struct student {
    int roll_num;
    char name[128];
} student_t;

void print_struct(student_t *s) {
    printf("Roll num: %d, name: %s\n", s->roll_num, s->name);
}

int main() {
    student_t s1, s2;
    s1.roll_num = 1;
    strcpy(s1.name, "tom");
    s2 = s1;
    // 配列メンバーにはディープコピーが行われるため、s1 の内容は影響を受けない
    s2.name[0] = 'T';
    s2.name[1] = 'O';
    s2.name[2] = 'M';
    print_struct(&s1);
    print_struct(&s2);
    return 0;
}

実行結果

上記のコードをコンパイルして実行すると、次の出力が得られます。

Roll num: 1, name: tom
Roll num: 1, name: TOM

出力のポイント

s2 = s1; という代入の後で s2.name の先頭3文字を変更していますが、s1 側の名前は「tom」のまま変化していません。これは、配列メンバーに対してディープコピーが行われ、s1 と s2 がそれぞれ独立した name 配列を持っていることを示しています。

なぜ配列だけディープコピーされるのか?

C言語における構造体の代入は、構造体全体のメモリ内容を丸ごと複製する動作です。char name[128] のような配列メンバーは、構造体内に実データが埋め込まれているため、代入時にその内容まで一緒にコピーされます。

一方、メンバーがポインタ(例:char *name)だった場合はどうなるでしょうか。この場合、コピーされるのは「アドレス値」だけです。その結果、両方の構造体が同じメモリ領域を共有することになり、片方の文字列を書き換えるともう片方にも影響が及びます。これがシャローコピーに伴う典型的な問題です。構造体内で文字列を扱う場合は、固定長配列を使うか、strdup() などで明示的にメモリを確保・複製することが推奨されます。

  1. C/C++の多次元配列とは?基本概念から動的メモリ確保まで徹底解説

    C/C++における多次元配列とは、簡単に言えば「配列の配列」として定義されるデータ構造です。多次元配列では、データが表形式(行優先順/row-major order)でメモリ上に格納されます。 以下の図は、3×3×3の次元を持つ多次元配列のメモリ割り当て戦略を示したものです。 アルゴリズム 2次元配列を動的に確保し、操作するための基本的な手順は以下の通りです。 Begin 配列の次元を宣言する new演算子を使用して2次元配列 a[][] を動的に確保する 配列に要素を格納する 配列の内容を出力する deleteによってメモリを解放する End サン

  2. C言語の多次元配列とは?行優先・列優先の仕組みとサンプルコード

    多次元配列とは配列とは、同種のデータ(ホモジニアスなデータ)をまとめて管理するための基本的なデータ構造です。配列の要素は、メモリ上の連続した領域に順番に配置されます。しかし実際のプログラミングでは、1次元の配列だけでは不十分なケースが少なくありません。例えば、表形式のデータや行列を扱う場合には、2次元配列やさらに多くの次元を持つ多次元配列を作成する必要があります。行優先方式と列優先方式多次元配列をメモリ上に表現する方法には、大きく分けて2つのアプローチがあります。ひとつは行優先(Row-Major)方式、もうひとつは列優先(Column-Major)方式です。r行 c列の2次元配列を考えてみま