- ベストアンサー
構造体のサンプルのソースなんですけど・・
自分が勉強するのに使ってる参考書にのってるサンプルのソースを自分なりにいじってみたら、コンパイルはできるのに実行すると、「不正な処理を行ったので強制終了します」とメッセージがでて実行できません。 ソースは↓ #include<stdio.h> #include<string.h> struct kakakutyp{ int teika; int waribiki; int yuutai; }; struct syohintyp{ char name[30]; struct kakakutyp kakaku; int zaiko; }; main() { struct syohintyp *sp; strcpy(sp->name,"システム手帳B-386"); sp->kakaku.teika=8500; sp->kakaku.waribiki=7900; sp->kakaku.yuutai=7600; sp->zaiko=32; printf("品名:%s\n",sp->name); printf("定価価格:%d\n",sp->kakaku.teika); printf("割引価格:%d\n",sp->kakaku.waribiki); printf("優待価格:%d\n",sp->kakaku.yuutai); printf("在庫個数:%d\n",sp->zaiko); } になってます。なんでじっこうできないんでしょうか?参考書では、ドット演算子を使ってたんですが、それをアロー演算子に直したつもりです。 よろしくお願いします。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
struct syohintyp *sp; の宣言では、syohintyp のポインタのみを宣言したに過ぎず、実際にデータの 格納されるべきエリアが確保できていません。したがって、 struct syohintyp と同じ大きさのメモリーを確保する命令を発行し、返ってきたポインタを sp に格納した後でないと、 strcpy(sp->name,"システム手帳B-386"); を実行したときに、「不正な処理」となります。 このプログラムは実行時 *sp は 「不定」となります。 「不定」つまり、どこを示しているかわからないポインタを使って、 アクセスしようとすると、「不正な処理」として強制終了します。 元の例題では、 struct syohintyp sp; と宣言されていたはずですが、この場合は、コンパイル時に struct syohintyp のサイズのエリアを確保しますので(プログラムエリアに含んである) ドット演算子で構造体を扱うことができます。 また、簡単に実行できるようにするには、 struct syohintyp *sp; の後に struct syohintyp spp; sp = &spp; を追加すれば、実行できるようになります。
その他の回答 (3)
- bugmaru
- ベストアンサー率38% (76/195)
main()関数で宣言している、struct syohintyp *sp は syohintyp のポインタ型を宣言してるに過ぎなくて、実態を取っていません。 実態を取っていないところに、値を代入してるので不正なエラーになります。 参考書を良く見てどこかに実態を宣言しているはずです。 ポインタの概念は頭の中でメモリ空間が想像できるくらい良く理解してください。 それからC言語は、文法として間違っていなければコンパイルは通ってしまいます 不正なメモリ操作を行うかどうかのチェックは一切してくれませんので、注意深く プログラミングしてください。
- madman
- ベストアンサー率24% (612/2465)
>struct syohintyp *sp; 宣言がポインタになっています。 ポインタで宣言するとメモリー上にはポインタアドレスを格納する領域しか確保されません。すなわち4バイトのみです。 実態で宣言するか(struct syohintyp sp;)、ポインタで宣言した変数をmalloc等を利用して、実メモリ領域を確保する必要があります。 まぁ、そうしないと使えないと思ってください。
- osamuy
- ベストアンサー率42% (1231/2878)
デバッガを利用して、変数の中身を追っていけば、実感できると思いますが、ポインタ変数を定義するだけでは、構造体自体の領域が、実際には確保されません。 例えば、以下のように struct syohintyp sbuf; struct syohintyp *sp; sp = &sbuf; strcpy(sp->name,"システム手帳B-386"); のように、ポインタ変数の参照先が、ちゃんとメモリが確保されている領域であるように、プログラミングして下さい。
お礼
回答ありがとうございます。 ポインタも一通りは勉強したつもりだったんですが、まだまだ勉強不足でした(-.-) 今回の質問で、また少し頭よくなった気がします。これからも張り切って勉強してみます。 回答してくださった皆さんありがとうございます。 お礼をまとめてしまって申し訳ないです。