メモリ確保(再)
メモリ確保(再)
こんばんわ、C言語の勉強を始めたものです。
以下の構造体でメモリ確保を行うには
SAMPLE *sample = (SAMPLE *) malloc(sizeof(SAMPLE));
と確保できるのはわかりました。
しかし例えば
SAMPLE *sample = (SAMPLE *) malloc(500);
と余分にメモリを確保した場合、メモリ的にどういう構造になるのでしょうか?
handle→4バイト
number→4バイト
str→4バイト
[handle(4バイト)] + [number(4バイト)] + [str(4バイト)] + [余分なゴミメモリ(488バイト)]
①こんな構造のメモリ領域ができあがると考えていますが、正しいでしょうか?
SAMPLE *sample = (SAMPLE *) malloc(500)とした後
sample->str = (char*)malloc(600);
とした場合、
②この場合、構造体メンバーの確保領域が、構造体の確保領域を超えているのですが、これはどういう状態になりますか?
エラーにはなりませんでした。
SAMPLE *sample = (SAMPLE *) malloc(500)とした後
sample->str = (char*)malloc(300);
とした場合、
③構造体のメモリ領域は以下のようになると考えています。正しいでしょうか?
[handle(4バイト)] + [number(4バイト)] + [str(300バイト)] + [余分なゴミメモリ(192バイト)]
①~③が質問です。
以上、よろしくお願いいたします。
以下の構造体でメモリ確保を行うには
SAMPLE *sample = (SAMPLE *) malloc(sizeof(SAMPLE));
と確保できるのはわかりました。
しかし例えば
SAMPLE *sample = (SAMPLE *) malloc(500);
と余分にメモリを確保した場合、メモリ的にどういう構造になるのでしょうか?
handle→4バイト
number→4バイト
str→4バイト
[handle(4バイト)] + [number(4バイト)] + [str(4バイト)] + [余分なゴミメモリ(488バイト)]
①こんな構造のメモリ領域ができあがると考えていますが、正しいでしょうか?
SAMPLE *sample = (SAMPLE *) malloc(500)とした後
sample->str = (char*)malloc(600);
とした場合、
②この場合、構造体メンバーの確保領域が、構造体の確保領域を超えているのですが、これはどういう状態になりますか?
エラーにはなりませんでした。
SAMPLE *sample = (SAMPLE *) malloc(500)とした後
sample->str = (char*)malloc(300);
とした場合、
③構造体のメモリ領域は以下のようになると考えています。正しいでしょうか?
[handle(4バイト)] + [number(4バイト)] + [str(300バイト)] + [余分なゴミメモリ(192バイト)]
①~③が質問です。
以上、よろしくお願いいたします。
Re: メモリ確保(再)
メモリアドレスが32bitの場合はそのようになります。Cユーザー さんが書きました: SAMPLE *sample = (SAMPLE *) malloc(500);
と余分にメモリを確保した場合、メモリ的にどういう構造になるのでしょうか?
handle→4バイト
number→4バイト
str→4バイト
[handle(4バイト)] + [number(4バイト)] + [str(4バイト)] + [余分なゴミメモリ(488バイト)]
①こんな構造のメモリ領域ができあがると考えていますが、正しいでしょうか?
構造体メンバーの確保領域は、構造体の確保領域を超えていません。Cユーザー さんが書きました: SAMPLE *sample = (SAMPLE *) malloc(500)とした後
sample->str = (char*)malloc(600);
とした場合、
②この場合、構造体メンバーの確保領域が、構造体の確保領域を超えているのですが、これはどういう状態になりますか?
エラーにはなりませんでした。
この場合もsampleは4byteです。
違います。Cユーザー さんが書きました: SAMPLE *sample = (SAMPLE *) malloc(500)とした後
sample->str = (char*)malloc(300);
とした場合、
③構造体のメモリ領域は以下のようになると考えています。正しいでしょうか?
[handle(4バイト)] + [number(4バイト)] + [str(300バイト)] + [余分なゴミメモリ(192バイト)]
[handle(4バイト)] + [number(4バイト)] + [str(4バイト)] + [余分なゴミメモリ(488バイト)]
と
[(300バイト)]
の2つの領域が確保されます。この領域は連続しているとは限りません。
そして、strへ300byteの領域の先頭のアドレスが代入されます。
Re: メモリ確保(再)
ご返信ありがとうごさます。
なるほど、そういう仕組みなんですね。
もう1点質問させてください。逆に、
handle(4バイト)] + [number(4バイト)] + [str(300バイト)] + [余分なゴミメモリ(192バイト)]
となるような、確保領域の再設定?は可能でしょうか?
可能であれば方法をご教授いただきたいです。
なるほど、そういう仕組みなんですね。
もう1点質問させてください。逆に、
handle(4バイト)] + [number(4バイト)] + [str(300バイト)] + [余分なゴミメモリ(192バイト)]
となるような、確保領域の再設定?は可能でしょうか?
可能であれば方法をご教授いただきたいです。
Re: メモリ確保(再)
返信ありがとうございます。
その方法は1つの手ではあるのですが
後から構造体メンバの文字列のメモリを確保したいんです。
だとあらかじめ決まった分しか確保できません。
其のため としておいて、後からメモリを確保したいんですよね。
それでhandle(4バイト) + number(4バイト) + str(300バイト)
というような無駄なメモリもなくメモリを使いたい。実はこれが一番やりたいことです。
何か方法はないでしょうか
以上、よろしくお願いいたします。
その方法は1つの手ではあるのですが
後から構造体メンバの文字列のメモリを確保したいんです。
だとあらかじめ決まった分しか確保できません。
其のため としておいて、後からメモリを確保したいんですよね。
それでhandle(4バイト) + number(4バイト) + str(300バイト)
というような無駄なメモリもなくメモリを使いたい。実はこれが一番やりたいことです。
何か方法はないでしょうか
以上、よろしくお願いいたします。
Re: メモリ確保(再)
ご返信ありがとうございます。
また疑問が1つできました。
前のレスで300の領域の先頭アドレスが代入されるとありました。
その場合、構造体のメモリ確保時のstrのメモリは無駄メモリになる感じでしょうか?
また疑問が1つできました。
前のレスで300の領域の先頭アドレスが代入されるとありました。
その場合、構造体のメモリ確保時のstrのメモリは無駄メモリになる感じでしょうか?
Re: メモリ確保(再)
300バイト確保した分がどこにあるか、というアドレス値を保持するために必須です。Cユーザー さんが書きました: その場合、構造体のメモリ確保時のstrのメモリは無駄メモリになる感じでしょうか?
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。
プログラムは思ったとおりには動かない。書いたとおりに動く。
Re: メモリ確保(再)
構造体の最後のメンバを要素数1の配列にします。Cユーザー さんが書きました:というような無駄なメモリもなくメモリを使いたい。実はこれが一番やりたいことです。
#処理系によっては要素数0が使えます。 必要な配列の要素数分を余分にメモリ確保します。 こうするとsample->strは要素数が300あるかのように使えます。
Re: メモリ確保(再)
標準C的には,要素数を記述しない,ですね。ISLe さんが書きました:構造体の最後のメンバを要素数1の配列にします。
#処理系によっては要素数0が使えます。
# ISO/IEC 9899:1999 6.7.2.1 Structure and union specifiers ¶16
標準Cが使えるならば, とするとよいでしょう。
この場合,1を引く作業は不要です。
ただ,標準Cではあるものの標準C++ではない (標準C++の標準CとのCompatibility欄にすら書いていない) のが問題点ですが。
# 配列まわりはCとC++で非互換が……。
Re: メモリ確保(再)
これってWin32APIの構造体でよく見かけますね。ISLe さんが書きました:構造体の最後のメンバを要素数1の配列にします。Cユーザー さんが書きました:というような無駄なメモリもなくメモリを使いたい。実はこれが一番やりたいことです。
#処理系によっては要素数0が使えます。 必要な配列の要素数分を余分にメモリ確保します。 こうするとsample->strは要素数が300あるかのように使えます。
SDKのIncludeヘッダで、"[1]"で検索すると結構ヒットする。
これを使用する場合、たいていはどれだけの長さがあるかも構造体のメンバに入れてます。
例:winnt.hの一部
typedef struct _JOBOBJECT_BASIC_PROCESS_ID_LIST {
DWORD NumberOfAssignedProcesses;
DWORD NumberOfProcessIdsInList;
ULONG_PTR ProcessIdList[1];
} JOBOBJECT_BASIC_PROCESS_ID_LIST, *PJOBOBJECT_BASIC_PROCESS_ID_LIST;
typedef struct _FILE_NOTIFY_INFORMATION {
DWORD NextEntryOffset;
DWORD Action;
DWORD FileNameLength;
WCHAR FileName[1];
} FILE_NOTIFY_INFORMATION, *PFILE_NOTIFY_INFORMATION;
スレ汚しすみません。
written by へにっくす