- PR -

C言語のメモリ領域確保に関して

1
投稿者投稿内容
sin
会議室デビュー日: 2007/02/22
投稿数: 1
投稿日時: 2007-02-22 01:37
C言語を始めて3ヶ月の初心者です。
下記のような定義で、領域確保をしたいのですが、
うまい方法がわかりません。
ご存知の方いらっしゃいましたら、
御知恵をお貸し下さいませんでしょうか?

<test.h>
==================================
#define SIZE_A (5)

/* 親構造体 */
typedef struct {
int testInt;
testSmallStructT *testSmall; // 7バイト構造体の配列
char *testChar; // SIZE_A分の領域*配列数
} testBigStructT;

/* 7バイト構造体 */
typedef struct {
char str1[3];
char str2[4];
} testSmallStructT;

/* メンバ変数 */
testBigStructT gTest[10];
==================================
ここで、あらかじめ全体の領域サイズを算出して、
mallocにてエリア確保を行う方法を求めてます。
また、多数にmallocを使用するとメモリ確保失敗時に、
それまで確保したエリアの開放を行わなくてはいけなくなる懸念から、
できるだけ使用しないようにしたいのです。

メンバ変数gTestを10の配列で持ち、構造体testBigStructTの、
要素testSmallとtestCharを可変の配列として扱いたくポインタ定義をしており、
更に、testCharにSIZE_A(5byte)の領域を確保しようとしております。

最終的には、下記のような使い方をしたいのですが、
メモリ確保の方法がわかりません。
===================================
(EX:)
strcpy(gTest[0].testSmall[0].str1,"aaa");
strcpy(gTest[3].testSmall[2].str2,"bbb");
strcpy(gTest[6].testChar[3],"cccc");
===================================

開放も同様です。

大変申し訳御座いませんが、
ご指摘・ご指導願いませんでしょうか?

どうか宜しくお願い致します。
渋木宏明(ひどり)
ぬし
会議室デビュー日: 2004/01/14
投稿数: 1155
お住まい・勤務地: 東京
投稿日時: 2007-02-22 02:13
引用:

また、多数にmallocを使用するとメモリ確保失敗時に、
それまで確保したエリアの開放を行わなくてはいけなくなる懸念から、
できるだけ使用しないようにしたいのです。



ということなら、親構造体のメンバを動的に確保する必要も無さそうなので

引用:

<test.h>
==================================
#define SIZE_A (5)

/* 親構造体 */
typedef struct {
int testInt;
testSmallStructT testSmall; // 7バイト構造体の配列
char testChar[SIZE_A]; // SIZE_A分の領域*配列数
} testBigStructT;

/* 7バイト構造体 */
typedef struct {
char str1[3];
char str2[4];
} testSmallStructT;

/* メンバ変数 */
testBigStructT* gTest = malloc(sizeof(testBigStructT) * 10);
==================================



じゃ駄目なんでしょうか。
甕星
ぬし
会議室デビュー日: 2003/03/07
投稿数: 1185
お住まい・勤務地: 湖の見える丘の上
投稿日時: 2007-02-22 06:27
引用:

sinさんの書き込み (2007-02-22 01:37) より:
ここで、あらかじめ全体の領域サイズを算出して、
mallocにてエリア確保を行う方法を求めてます。
また、多数にmallocを使用するとメモリ確保失敗時に、
それまで確保したエリアの開放を行わなくてはいけなくなる懸念から、
できるだけ使用しないようにしたいのです。


そう言うのを懸念する気持ちはわかりますが、解放処理を関数にカプセル化するとか、C++のデストラクタを活用するとか考えたほうが利口です。忘れそうだから使わないという話なら、1回確保するも、5回確保するも同じだと思うのです。

でまぁ、似たようなことを行っているAPIがあります。
コード:
BYTE *p = malloc(allocsize);
testBigStructT *st;
st = p;
st.testSmall = p + sizeof(st);
st.testChar = p + sizeof(st) + sizeof(testSmallStructT);


ってな感じでメモリを振り分ける処理を自分で各わけです・・・が、ふつうはやらないと思います。
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2007-02-22 06:52
アライメント調整

_________________
とっちゃん
大ベテラン
会議室デビュー日: 2005/07/19
投稿数: 203
投稿日時: 2007-02-22 12:17
typedef struct {
int testInt;
testSmallStructT *testSmall; // 7バイト構造体の配列
char *testChar; // SIZE_A分の領域*配列数
} testBigStructT;


typedef struct {
int testInt;
testSmallStructT *testSmall; // 7バイト構造体の配列
char testChar[SIZE_A]; // SIZE_A分の領域*配列数
} testBigStructT;
にして、あとは甕星さんが書いているようにアロケートした後くっつけるでいいんじゃないですか?

あとは、親構造体の順番を変えてもよいのなら、
typedef struct {
int testInt;
char testChar[SIZE_A]; // SIZE_A分の領域*配列数
testSmallStructT testSmall[1]; // 7バイト構造体の配列
} testBigStructT;
としておいて、
malloc( sizeof(testBigStructT)+(sizeof(testSmallStructT)*(n-1)) );
とするやり方もあります。

いずれにしても、注意が必要なのはアライメント調整ですね。
mio
ぬし
会議室デビュー日: 2005/08/25
投稿数: 734
お住まい・勤務地: 神奈川県
投稿日時: 2007-02-22 13:20
小さなサイズや中途半端なサイズをmallocしようとしても、大抵はきりのいい数字で確保されるので、
やるならまとめてやったほうがメモリを無駄なく取得できるという面もありますね。
構造体のサイズはsizeof(名前)で取れたような。

Javaに慣れてしまうとmallocがわずらわしいこと。
1

スキルアップ/キャリアアップ(JOB@IT)