アプリ版:「スタンプのみでお礼する」機能のリリースについて

C初心者です。
宜しくお願い致します。

某社のSDKを参考にプログラムを作成しておりますが、構造体配列の初期化する方法がわからなくて困っています。
下記の構造体の初期化をしたいのですが、どのような方法で初期化すればいいかわからない状態です。

すいませんが、ご教授いただきたく宜しくお願い申し上げます。


typedef struct ioctl_videomode {
V2U_INT32 width;
V2U_INT32 height;
V2U_INT32 vfreq;
} V2U_PACKED V2U_VideoMode;

typedef struct v2u_rect {
V2U_INT32 x;
V2U_INT32 y;
V2U_INT32 width;
V2U_INT32 height;
} V2U_PACKED V2URect;

typedef struct ioctl_grabframe2 {
void * pixbuf;
V2U_INT32 pixbuflen;
V2U_UINT32 palette;
V2URect crop;
V2U_VideoMode mode;
V2U_INT32 imagelen;
V2U_INT32 retcode;
} V2U_GrabFrame2;

typedef struct {
V2U_GrabFrame2* frame;
char ftime[16];
}frameinfo;

void main()
{
frameinfo fr[512];

//初期化したい
→→ fr = (frameinfo*)malloc(sizeof(frameinfo)*512);
}


error C2106: '=' : 左のオペランドが、左辺値になっていません

A 回答 (9件)

No.1です。



No.8
>おそらくは、(1)に格納する値が void* であり、fと同じメモリを参照している為、
>(2)の開放処理を行うと、fr[0].frame->pixbufのメモリも開放され、エラーが発生しております。
が本当であれば、解放処理そのものの位置を見直す必要があります。
No.7で回答した
>V2U_GrabFrame2* f = FrmGrab_Frame();
>fr[0].frame = (V2U_GrabFrame2*)malloc(sizeof(V2U_GrabFrame2));
は実際のところ二次案で、結局はmalloc()で確保したものを最後に開放するという点に関しては全く違いはありませんから。

この回答への補足

度々のご回答誠にありがとうございました。

V2U_GrabFrame2* f を配列として格納し、開放処理を遅らせることで解決しました。

書き込んでくださった方々、いろいろとご指導いただきましてありがとうございました。
一応これでクローズしたいと思います。

補足日時:2009/10/01 21:15
    • good
    • 0
この回答へのお礼

度々のご回答誠にありがとうございました。

V2U_GrabFrame2* f を配列として格納し、開放処理を遅らせることで解決しました。

書き込んでくださった方々、いろいろとご指導いただきましてありがとうございました。
一応これでクローズしたいと思います。

お礼日時:2009/10/01 21:17

No.1です。



No.6
------------
メモリ領域をそのまま使用するのではなく、別のメモリfr[0].frameにfの情報を持たせたいのです。
理由は、SDKで
V2U_GrabFrame2* f = FrmGrab_Frame();
で取得した情報は直ぐに開放処理を行っているためです。
よって、解放前に別のメモリfrにfの情報を保持し、fを開放し、後でfrの情報を使用するものを作成したいと思っております。
開放されると、frの情報も同時に開放される為、取得できない状態です。
------------
であれば、別に V2U_GrabFrame2のメモリを確保しておくことです。
 fr[0].frame = (V2U_GrabFrame2*)malloc(sizeof(V2U_GrabFrame2);
のように予め領域をmalloc()で確保しておき、
 V2U_GrabFrame2* f = FrmGrab_Frame();
で取得されfに格納された内容を入れていくことです。

malloc()が嫌であれば、メモリを多量に消費しますが、
 typedef struct {
 V2U_GrabFrame2* frame;
 char ftime[16];
 }frameinfo;

 typedef struct {
 V2U_GrabFrame2 frame;  // <--ポインタではなく実体
 char ftime[16];
 }frameinfo;
と実体を確保しておき代入するという手もあります。

この回答への補足

何度もご教授いただきまして、ありがとうございます。
すいません、もう一点ご質問させていただきます。


V2U_GrabFrame2* f = FrmGrab_Frame();
fr[0].frame = (V2U_GrabFrame2*)malloc(sizeof(V2U_GrabFrame2));

fr[0].frame->crop = f->crop;
fr[0].frame->imagelen = f->imagelen;
fr[0].frame->mode = f->mode;
fr[0].frame->palette = f->palette;
fr[0].frame->pixbuf = f->pixbuf;  ‥‥ (1)
fr[0].frame->pixbuflen = f->pixbuflen;
fr[0].frame->retcode = f->retcode;

frmGrab_Release(f); ←f 開放処理  ‥‥ (2)
save_frame(fr[0].frame)←ここでエラー‥‥ (3)

上記の方法でやってみまして、fr[0].frameに値を格納することができました。
しかしながら、(3)のところでエラーがでております。

(2)をコメントアウトし実行すると、問題なく期待した処理が実行されます。

おそらくは、(1)に格納する値が void* であり、fと同じメモリを参照している為、(2)の開放処理を行うと、fr[0].frame->pixbufのメモリも開放され、エラーが発生しております。

これの実際の値を別のメモリに格納しようと思い、以下を実行してみましたが、エラーが出てしまいました。
DWORD aaaaa;
aaaaa = GlobalSize(f->pixbuf);
"ヒープが壊れていることが原因として考えられます。***.exe または読み込まれた DLL にバグがあります。"

やりたいこととしましては、
f->pixbuf(void*)の値を格納して、そのアドレスを fr[0].frame->pixbuf に代入し、実行したいと考えています。
しかしながら、f->pixbuf はどのような型で構成されているのかが、DLLの中で定義されている為、わからない状態です。
このような処理は可能なのでしょうか。

当初の質問からかなりずれたものになってしまいまして、申し訳ありません。
何度もすいませんが、ご回答いただけますようよろしくお願い申し上げます。

補足日時:2009/09/28 21:17
    • good
    • 0

>最初は


>memset(&fr, 0, sizeof(fr))
>にて初期化したつもりだったのですが、

memset(fr, 0, sizeof(fr))

ではだめですか?
間違っていたらごめんなさい。
    • good
    • 0

No.1です。


まずmalloc()関数に関連する「ポインタやメモリ操作」を理解することが先です。
SDKがどうこういう問題ではありません。

No.3
--------
SDKについている以下の関数
V2U_GrabFrame2* f = FrmGrab_Frame()
にて、関数より取得した値fを、構造体の変数fr[要素数].frameにコピーし、メモリにて保持させたいと考えております。

最初は
memset(&fr, 0, sizeof(fr))
にて初期化したつもりだったのですが、
fr[0].frame->crop.height = f->crop.height
にて
0x00401bbb でハンドルされていない例外が発生しました: 0xC0000005: 場所 0x00000018 に書き込み中にアクセス違反が発生しました。
--------
の例外エラーの理由だけ説明します。

>memset(&fr, 0, sizeof(fr))
は確かに「初期化」はしています。しかし、
>typedef struct {
>V2U_GrabFrame2* frame;
>char ftime[16];
>}frameinfo;
のメンバだけが初期化(0クリア)されている状態です。
ftime[]の0クリアは問題ありませんが、*frameはポインタです。参照する先のメモリアドレスを指定する必要がありますが、この時点では参照先のメモリアドレスが確保されておらず、アドレスも0が指定されています。
この状態で、
>fr[0].frame->crop.height = f->crop.height
とすれば、参照先が無いのですから例外エラーとなるのは必然です。

>V2U_GrabFrame2* f = FrmGrab_Frame()
で所得するメモリ領域をそのまま使用するのであれば、
 V2U_GrabFrame2* f = FrmGrab_Frame();
 fr[0].frame = f;
もしくは
 fr[0].frame = FrmGrab_Frame();
と記述することで解決できます。

この回答への補足

ご回答誠ありがとうございました。
すいませんが、再度ご質問させていただきたく思います。

>>V2U_GrabFrame2* f = FrmGrab_Frame()
>で所得するメモリ領域をそのまま使用するのであれば、
> V2U_GrabFrame2* f = FrmGrab_Frame();
> fr[0].frame = f;
>もしくは
> fr[0].frame = FrmGrab_Frame();
>と記述することで解決できます。


メモリ領域をそのまま使用するのではなく、別のメモリfr[0].frameにfの情報を持たせたいのです。
理由は、SDKで
V2U_GrabFrame2* f = FrmGrab_Frame();
で取得した情報は直ぐに開放処理を行っているためです。
よって、解放前に別のメモリfrにfの情報を保持し、fを開放し、後でfrの情報を使用するものを作成したいと思っております。
開放されると、frの情報も同時に開放される為、取得できない状態です。

説明不足で申し訳ありません。
お手数ですが、ご回答いただきたくよろしくお願い申し上げます。

補足日時:2009/09/28 09:07
    • good
    • 0

> fの構造をframeにそのまま保持できれば、どのような構造でもいいと思っております。



では、

V2U_GrabFrame2 frames[512];
frameinfo fr[512] = { { &frames[0] }, { &frames[1] }, ... };

のように512個分初期化子を記述すれば、文法上の「初期化」を用いて初期化することができます。
面倒ならループで「代入」してもよいと思います。
    • good
    • 0

fr[0].frame が保持するポインタは、どういった素性のものにするつもりでしょうか?


つまり、malloc等で割付けるのか、あるいは静的に用意したオブジェクトのアドレスを使うのかなどです。

どうしたいのかは、設計した本人にしかわかりませんので、十分な情報を補足してください。

この回答への補足

ご回答ありがとうございます。
>fr[0].frame が保持するポインタは、どういった素性のものにするつもりでしょうか?
>つまり、malloc等で割付けるのか、あるいは静的に用意したオブジェクトのアドレスを使うのかなどです。


typedef struct {
V2U_GrabFrame2* frame;
char ftime[16];
}frameinfo;
の、char ftime[16]には、V2U_GrabFrame2* frameに格納した時間を保持する為に用意したものです。
fの構造をframeにそのまま保持できれば、どのような構造でもいいと思っております。

上記の回答でよろしかったでしょうか。
なにぶん初心者なものですので、今後の為にもご教授いただければありがたいです。
度々申し訳ありませんが、ご回答の程宜しくお願い申し上げます。

補足日時:2009/09/25 23:56
    • good
    • 0

実際に何をやりたいのかがよく分かりませんが...



文法上の「初期化」を使って、frに割付け記憶域期間を持たせたいのであれば、

frameinfo *fr = malloc(sizeof(frameinfo)*512);

または

frameinfo (*fr)[512] = malloc(sizeof(frameinfo[512]));

としてください。

なお、この方法では、配列の各要素の値は不定になります。
構造体のメンバにポインタを含んでいますので、callocを使っても、あるいはmemsetでゼロクリアしても、問題解決にはなりません。
多分大丈夫だとは思いますが、処理系不明の状態ではそうとしかいえません。

この回答への補足

ご回答ありがとうございます。
実際にやりたいことを補足させていただきます。

SDKについている以下の関数
V2U_GrabFrame2* f = FrmGrab_Frame()
にて、関数より取得した値fを、構造体の変数fr[要素数].frameにコピーし、メモリにて保持させたいと考えております。

最初は
memset(&fr, 0, sizeof(fr))
にて初期化したつもりだったのですが、
fr[0].frame->crop.height = f->crop.height
にて
0x00401bbb でハンドルされていない例外が発生しました: 0xC0000005: 場所 0x00000018 に書き込み中にアクセス違反が発生しました。

のエラーが出て、どのように初期化すればいいかわからない状態になっております。

fr[0].frame のアドレスが、0x00000000 になっているのが原因かと考えておりますが、どのように初期化するとよいのでしょうか。

お手数ですが、再度ご回答いただきたくよろしくお願い申し上げます。

補足日時:2009/09/25 22:52
    • good
    • 0

以下の二つの方法があります。



(1)変数の宣言時に初期化する方法
void main()
{
 frameinfo fr[512] = {0};
}

(2)変数宣言後に初期化する方法
void main()
{
 frameinfo fr[512];
 memset(&fr,0,sizeof(fr));
}
→sizeof(fr)のみでサイズは取得可能
 理由:変数の宣言で配列の大きさが指定されているため
    sizeofで全体のバイト数が求められる。
    • good
    • 0

問題の結から。


malloc()は領域を初期化する関数ではありません。
宣言されたサイズのメモリを確保する関数で、出力される内容は確保したメモリの先頭アドレスになり、代入するための変数はポインタ方になります。

>error C2106: '=' : 左のオペランドが、左辺値になっていません
は、ポインタ型の値を実体を持つframeinfo型に入れようとしているために発生しています。

forループを使用して各メンバに適切な値を代入してください。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!