2.2.4. 構造体の割り当て方のバリエーション
配列のデータはnewで動的に割り当てるものの、固定長でサイズも小さい Array
構造
体の方は普通の変数として割り当てるという作り方の例です。
前の例とは、 Array
の割り当て、解放の関数と main
関数の中だけが違います。
割り当て・解放の関数は次のようになっています。
48// allocate an array.
49// returns true on success, false on failure.
50bool allocate_array_struct(int n, Array *par) {
51 par->pdata = new double[n];
52 if (par->pdata == nullptr) {
53 // could not allocate memory for the array.
54 return false;
55 }
56 // success.
57 par->n_size = n;
58 return true;
59}
60
61void free_array_struct(Array *ar) {
62 delete [] ar->pdata;
63}
前の例との相違点は、 Array
は割り当て済みで、その先の parray
の部分だけ
を割り当て・解放している点です。
65int main(int argc, const char *argv[])
66{
67 std::cout << "s004\n";
68
69 // allocate array dynamically on the heap area.
70 Array array1;
71 Array array2;
72 if (! allocate_array_struct(N_SIZE, &array1)) {
73 return EXIT_FAILURE;
74 }
75 if (! allocate_array_struct(N_SIZE, &array2)) {
76 free_array_struct(&array2);
77 return EXIT_FAILURE;
78 }
Array
型の変数 array1
と array2
は、 main
関数のローカル変数とし
て割り当てています。
80 // Array型の変数のアドレスを関数に渡す。
81 // 構造体のコピーを防ぐ昔の書き方(今は参照型を使う)
82 // 関数の側ではArray型のポインタ変数で受ける。
83 std::cout << "Before initialization\n";
84 print_data_struct(&array1);
85
86 set_dummy_data_struct(&array1);
87 std::cout << "After initialization\n";
88 print_data_struct(&array1);
89
90 copy_data_struct(&array2, &array1);
91 std::cout << "After array copy\n";
92 print_data_struct(&array2);
93
94 // return allocated memory to OS
95 // new に成功した場合にのみ delete を呼ぶこと。
96 free_array_struct(&array1);
97 free_array_struct(&array2);
98
99 return EXIT_SUCCESS; // exit status code 0
100}
全体のソースを以下に示します:
1// s004: dynamically allocated array held on a struct
2// along with the data count.
3//
4// the struct is allocated as a whole value rather than a pointer.
5//
6#include <iostream>
7#include <cassert>
8
9const int N_SIZE = 10;
10
11// pdataとn_sizeという項目を持つ構造体を宣言する。
12// Array型の変数が使えるようになる。
13struct Array {
14 double *pdata;
15 int n_size;
16};
17
18// same functions as s001.cpp
19
20// function to set dummy data to the array
21void set_dummy_data_struct(Array *par)
22{
23 for (int i = 0; i < par->n_size; i++) {
24 par->pdata[i] = static_cast<double>(i) / static_cast<double>(par->n_size);
25 }
26}
27
28void copy_data_struct(Array *pdest, const Array *psrc)
29{
30 assert(pdest->n_size == psrc->n_size);
31 for (int i = 0; i < pdest->n_size; i++) {
32 pdest->pdata[i] = psrc->pdata[i];
33 }
34}
35
36void print_data_struct(const Array *par)
37{
38 std::cout << "[";
39 for (int i = 0; i < par->n_size; i++) {
40 std::cout << par->pdata[i];
41 if (i < par->n_size - 1) {
42 std::cout << ", ";
43 }
44 }
45 std::cout << "]\n";
46}
47
48// allocate an array.
49// returns true on success, false on failure.
50bool allocate_array_struct(int n, Array *par) {
51 par->pdata = new double[n];
52 if (par->pdata == nullptr) {
53 // could not allocate memory for the array.
54 return false;
55 }
56 // success.
57 par->n_size = n;
58 return true;
59}
60
61void free_array_struct(Array *ar) {
62 delete [] ar->pdata;
63}
64
65int main(int argc, const char *argv[])
66{
67 std::cout << "s004\n";
68
69 // allocate array dynamically on the heap area.
70 Array array1;
71 Array array2;
72 if (! allocate_array_struct(N_SIZE, &array1)) {
73 return EXIT_FAILURE;
74 }
75 if (! allocate_array_struct(N_SIZE, &array2)) {
76 free_array_struct(&array2);
77 return EXIT_FAILURE;
78 }
79
80 // Array型の変数のアドレスを関数に渡す。
81 // 構造体のコピーを防ぐ昔の書き方(今は参照型を使う)
82 // 関数の側ではArray型のポインタ変数で受ける。
83 std::cout << "Before initialization\n";
84 print_data_struct(&array1);
85
86 set_dummy_data_struct(&array1);
87 std::cout << "After initialization\n";
88 print_data_struct(&array1);
89
90 copy_data_struct(&array2, &array1);
91 std::cout << "After array copy\n";
92 print_data_struct(&array2);
93
94 // return allocated memory to OS
95 // new に成功した場合にのみ delete を呼ぶこと。
96 free_array_struct(&array1);
97 free_array_struct(&array2);
98
99 return EXIT_SUCCESS; // exit status code 0
100}
実行例を示します
% ./s004
s004
Before initialization
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
After initialization
[0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]
After array copy
[0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]