• ベストアンサー

構造体のサンプルのソースなんですけど・・

自分が勉強するのに使ってる参考書にのってるサンプルのソースを自分なりにいじってみたら、コンパイルはできるのに実行すると、「不正な処理を行ったので強制終了します」とメッセージがでて実行できません。 ソースは↓ #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); } になってます。なんでじっこうできないんでしょうか?参考書では、ドット演算子を使ってたんですが、それをアロー演算子に直したつもりです。 よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • moccha
  • ベストアンサー率28% (20/71)
回答No.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; を追加すれば、実行できるようになります。

sin11
質問者

お礼

回答ありがとうございます。 ポインタも一通りは勉強したつもりだったんですが、まだまだ勉強不足でした(-.-) 今回の質問で、また少し頭よくなった気がします。これからも張り切って勉強してみます。 回答してくださった皆さんありがとうございます。 お礼をまとめてしまって申し訳ないです。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (3)

  • bugmaru
  • ベストアンサー率38% (76/195)
回答No.3

main()関数で宣言している、struct syohintyp *sp は syohintyp のポインタ型を宣言してるに過ぎなくて、実態を取っていません。 実態を取っていないところに、値を代入してるので不正なエラーになります。 参考書を良く見てどこかに実態を宣言しているはずです。 ポインタの概念は頭の中でメモリ空間が想像できるくらい良く理解してください。 それからC言語は、文法として間違っていなければコンパイルは通ってしまいます 不正なメモリ操作を行うかどうかのチェックは一切してくれませんので、注意深く プログラミングしてください。

全文を見る
すると、全ての回答が全文表示されます。
  • madman
  • ベストアンサー率24% (612/2465)
回答No.2

>struct syohintyp *sp; 宣言がポインタになっています。 ポインタで宣言するとメモリー上にはポインタアドレスを格納する領域しか確保されません。すなわち4バイトのみです。 実態で宣言するか(struct syohintyp sp;)、ポインタで宣言した変数をmalloc等を利用して、実メモリ領域を確保する必要があります。 まぁ、そうしないと使えないと思ってください。

全文を見る
すると、全ての回答が全文表示されます。
  • osamuy
  • ベストアンサー率42% (1231/2878)
回答No.1

デバッガを利用して、変数の中身を追っていけば、実感できると思いますが、ポインタ変数を定義するだけでは、構造体自体の領域が、実際には確保されません。 例えば、以下のように struct syohintyp sbuf; struct syohintyp *sp; sp = &sbuf; strcpy(sp->name,"システム手帳B-386"); のように、ポインタ変数の参照先が、ちゃんとメモリが確保されている領域であるように、プログラミングして下さい。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • 構造体についてです。

    身体測定表を作っていて最初に作ったデータを変更して表示したいのですがNo1の168cm→162cm No2の74kg→74.5kg  No3の20歳→19歳 No4の田中三郎→小林三郎 (No3と4は構造体ポインタを使ってデータを変更) 全データを表示させてその後No1と3の名前~体重を丸ごと入れ替えて全データを表示させたいのですがエラーがでてしまいます。 分かる人がいましたらどこを直したらいいか教えて下さい。 #include <stdio.h> #include <string.h> struct data{ int no; char name[21]; int age; int height; float weight; }; struct data *sp; void main(){ int i; struct data a[4]={ {1,"鈴木太郎",23,168,60}, {2,"山本次郎",17,180,74}, {3,"山田花子",20,156,53}, {4,"田中三郎",35,172,68}, }; struct data b; for(i=0;i<4;i++){ printf("番号 :%d\n",a[i].no); printf("名前 :%s\n",a[i].name); printf("年齢 :%d歳\n",a[i].age); printf("身長 :%dcm\n",a[i].height); printf("体重 :%4.1fkg\n\n",a[i]. weight); } a[0].height=162; a[1].weight=74.5; *sp[2].age=19; strcpy(*sp[3].name,"小林三郎"); for(i=0;i<=4;i++){ b=a[0]; a[0]=a[2]; a[2]=b; a[0].no=1; a[2].no=3; } for(i=0;i<=4;i++){ printf("番号 :%d\n",a[i].no); printf("名前 :%s\n",a[i].name); printf("年齢 :%d歳\n",a[i].age); printf("身長 :%dcm\n",a[i].height); printf("体重 :%4.1fkg\n\n",a[i].weight); } }

  • 構造体の構造体 引数

    構造体の中の構造体の関数の引き渡し方法がわかりません。 下記ソースで試したのですが、うまくいきませんでした。 助言お願いいたします。 //repo.c #include <stdio.h> #include <string.h> #include <stdlib.h> #include <ctype.h> #define NUM 20 #define MAX 15 struct seiseki{ float shu[3]; }; struct seito{ char name[NUM]; int age; struct seiseki kekka; }; void input(struct seito *p); void s_input(struct seiseki *p); void ss_input(struct seiseki *data); int main(){ int i; struct seito data[2]; for(i=0;i<2;i++){ printf("------------------------------\n"); printf("%d人目",i+1); input(&data[i]); } printf("%f\n",data[0].kekka.shu[0]); printf("%f\n",data[0].kekka.shu[1]); printf("%f\n",data[0].kekka.shu[2]); //data[1]に格納できない。 printf("%f\n",data[1].kekka.shu[0]); printf("%f\n",data[1].kekka.shu[1]); printf("%f\n",data[1].kekka.shu[2]); return 0; } void input(struct seito *p){ printf("名前->"); scanf("%s",p->name); printf("年齢->"); scanf("%d",p->age); s_input(&(p->kekka)); } void s_input(struct seiseki *data){ printf("国語->"); ss_input(data); printf("算数->"); ss_input(data); printf("英語->"); ss_input(data); } //下記関数で成績をchar型で受け取り、数値化したい。 void ss_input(struct seiseki *data){ char p[100]; int i=0; static int o=0; scanf("%s",p); while( p[i] != '\0'){ if(isdigit(p[i])==0){ printf("再入力してください"); scanf("%s",p); } i++; } data->shu[o]=atof(p); printf("%f\n",data->shu[o]); o++; }

  • 構造体の使い方

    構造体の基本的な使い方を練習しようと思ったのですが、 なかなかスムーズにいきません。 p.d=10; の部分がおかしいようなのですが、色々試してもコンパイルできませんでした。 正しい使い方を教えていただけないでしょうか ソース ↓ #include<stdio.h> struct type{ int a; float b;  double c; }var,*p; main(){ c=9.87;      p=&var; p.d=10; p->b=1.2; printf("int:%d\n",*p); printf("float:%.1f\n",&p); printf("double:%.3lf\n",c); return 0; }

  • プログラミング構造体について。

    include<stdio.h> #include<stdlib.h> #include<string.h> struct person{ char name[10]; int gender; int age; }; void printPersonList(struct person *person_p, int size); void outputPersonList(struct person *person_p, int size); double getAverageOfAge(struct person *person_p, int size); int countMales(struct person *person_p, int size); int countFemales(struct person *person_p, int size); int main(void){ struct person *person_p; int i, count, gender, age, maleCount, femaleCount; char name[20]; double average; printf("登録する人数を入力してください。\n"); scanf("%d", &count); person_p = (struct person*)malloc(sizeof(struct person)* count); for(i=0; i < count; i++){ printf("名前・性別(男性:0, 女性:1)・年齢をスペース区切りで入力してください。\n"); scanf("%s %d %d", name, &gender, &age); strcpy((person_p + i) -> name, name); (person_p + i) -> gender = gender; (person_p + i) -> age = age; } printPersonList(person_p, count); outputPersonList(person_p, count); average = getAverageOfAge(person_p, count); printf("平均年齢:%f\n", average); maleCount = countMales(person_p, count); femaleCount = countFemales(person_p, count); printf("男性:%d名, 女性:%d名\n", maleCount, femaleCount); free(person_p); return 1; } void printPersonList(struct person *person_p, int size){ int i; printf("登録リスト\n"); printf(" name | gender | age\n"); printf("----------+--------+-----\n"); for(i=0; i < size; i++){ printf("%10s | %1d | %2d\n", (person_p + i) -> name, (person_p + i) -> gender, (person_p + i) -> age); } } void outputPersonList(struct person *person_p, int size){ FILE *output; int i; if((output = fopen("meibo.c", "w")) == NULL){ printf("meibo.cを開けませんでした。\n"); return; } for(i=0; i < size; i++){ fprintf(output, "%s, %d, %d\n", (person_p + i) -> name, (person_p + i) -> gender, (person_p + i) -> age); } fclose(output); } 残り3つの関数をすべて定義する(それぞれ10行程度) getAverageOfAge, countMales, countFemales どう定義すればいいのか教えてください。お願いします。

  • リストの削除について(構造体)

    リストの削除のプログラムを実行して行ってみると、リストの削除処理中にプログラムが終わって変更後処理がうまく表示されません。どこが間違っているかが分からないしだいです。返答のほどよろしくお願いいたします。 #include<stdio.h> #include<malloc.h> #include<string.h> struct list{ char name[20]; int age; struct list *next; }; void main(void) { struct list *head, *p, *n, *old; char key[20]; /*ダミーノード作成*/ head = (struct list*)malloc(sizeof(struct list)); old = head; while(p = (struct list*)malloc(sizeof(struct list)), printf("name age入力\n"), scanf("%s %d", p -> name, &p -> age) != EOF){ old -> next = p; old = p; } free(p); old -> next = NULL; p = head -> next; printf("変更前リスト\n"); while(p != NULL){ printf("name:%s age:%d\n",p -> name, p -> age); p = p -> next; } printf("削除key入力(name)\n"); gets(key); n = head; while(n != NULL){ old = n; n = n -> next; //printf("n -> name %s\n", n -> name); if(strcmp(n -> name, key) == 0){ printf("%s削除\n", key); //printf("n -> name %s old -> name %s\n", n -> name, old -> name); old -> next = n -> next; } } p = head -> next; printf("変更後リスト\n"); while(p != NULL){ printf("name:%s age:%d\n", p -> name, p -> age); p = p -> next; } }

  • C言語での構造体

    C言語の構造体で配列を扱うとき、 struct ○○{  char ○○[○] とすれば出来ますが、同じようにして構造体で二次元配列を扱うことは出来ますか? 一度組んでみたのですが、 #include<stdio.h> struct aaa{ int no; char name[128]; char y_name[128]; char n_name[128]; char s_name[128][128]; }; int main(void){ int i; struct aaa iryo[99]; printf("入力前\n"); /* 構造体配列に scanf()でデータを入力 */ for(i = 0; i < 3; i++) { // printf("input...\n"); scanf("%d", &iryo[i].no); scanf("%s", iryo[i].name); scanf("%s", iryo[i].y_name); scanf("%s", iryo[i].n_name); scanf("%s", iryo[i].s_name); } printf("入力後\n"); printf("出力前\n"); /* 入力データの確認 */ for(i = 0; i < 3; i++) { printf("番号:%02d 内容:%s Y分岐:%s N分岐:%s 他分岐:%s\n", iryo[i].no, iryo[i].name, iryo[i].y_name, iryo[i].n_name, iryo[i].s_name); } printf("出力後\n"); printf("%d",sizeof(struct aaa)); return 0; } としたら、エラーは出ませんが、実行すると何も表示されませんでした。

  • 構造体の配列について

    構造体配列を使った簡単なプログラムを組んでいるのですが、以下のソースコードをコンパイルし、実行したのですが、うまくいきません。 どなたかお力をお貸しください。 ・やりたい事 配列に以下のようにデータをscanf関数を使って入れたいです。 ----[0]---[1]---[2]--- [0] 1 | "あ" | "猫" | [1] 2 | "い" | "亀" | [2] 3 | "う" | "狐" | -登録する内容 番号、名前、好きなもの動物 ■ソース #include <stdio.h> struct hyou { int box[3][3]; }; int main(){ struct hyou *da; int i; for(i=0;i<2;i++){ printf("番号:\n");   scanf("%d",&da->box[i][0]); printf("名前:\n");   scanf("%s",&da->box[i][1]); printf("好きなもの:\n");   scanf("%s",&da->box[i][2]); } //テスト(2件表示) for(i=0;i<2){ printf("番号:\n"); printf("%d",a->box[i][0]); printf("名前:\n"); printf("%s",a->box[i][1]); printf("好きなもの:\n"); printf("%s",a->box[i][2]); } } //構造体配列の意味が違っていたらすみません。 以上、宜しくお願いします。

  • 構造体について

    5件のデータをRECORDに追加したいのですが、 RECORD inputdata(void)の宣言文エラーなどのコンパイルエラー。それと、inputdataを用いてどうやって5件のデータを入れたらいいかがわかりません。教えてください。 #define SIZE 5 #include <stdio.h> typedef struct{ int yy; int mm; int dd; }YMD; typedef struct{ char name[20]; YMD birthday; int age; }RECORD; RECORD inputdata(void); void main(void) { int i; for(i = 0;i < SIZE;i++){ inputdata(); } RECORD inputdata(void) { RECORD person; printf("名前>"); scanf("%s", person.name); printf("誕生日入力\n"); printf("年>"); scanf("%d", person.birthday.yy); printf("月>"); scanf("%d", person.birthday.mm); printf("日>"); scanf("%d", person.birthday.dd); return person; }

  • 構造体とポインタについて教えてください。

    #include <stdio.h> typedef struct ningen { char *name; char *sex; int age; } NINGEN; NINGEN data = {"牧村 五郎",NULL,30}; char mf[2][3] = {"男","女"}; void main(void) { data.sex=mf[0]; printf("%s (%s) %d歳\n", data.name, data.sex, data.age); } このプログラムで実行結果は 牧村 五郎 (男) 30歳 となるのですが、最初の typedef struct ningen { char *name; char *sex; int age; } NINGEN; のところで、nameとsexはアドレスで宣言しているので printf("%s (%s) %d歳\n", data.naem, data.sex, data.age);でのdata.naem, data.sexでの対象もアドレスを示していると思うのですが、 結果は値を表示しているのはなぜでしょうか?

  • c言語 構造体

    大学での内容なのですが,『名前,数学の点数,英語の点数,国語の点数を格納できる(メンバに持つ)構造体を宣言し,この構造体の配列を用いて,3人分の情報をキーボードから入力後,各科目の平均点を画面に表示するプログラムを作成せよ.』という問題で,自分なりに作ってみたのですがうまくいきません.どなたか教えていただけませんか? 一応自分で作ったものを下に載せておきます. ================================================================ #include <stdio.h> #include <string.h> struct test { char name[20]; int sugaku; int eigo; int kokugo; }; int main(void) { struct test suzuki; int (suzuki.sugaku), (suzuki.eigo), (suzuki.kokugo); strcpy(suzuki.name, "Suzuki"); printf("氏名:鈴木 一馬\n"); printf("数学:"); scanf("%d", &suzuki.sugaku); printf("英語:"); scanf("%d", &suzuki.eigo); printf("国語:"); scanf("%d", &suzuki.kokugo); struct test tanaka; int tanaka.sugaku, tanaka.eigo, tanaka.kokugo; strcpy(tanaka.name, "Tanaka"); printf("氏名:田中 二郎\n"); printf("数学:"); scanf("%d", &tanaka.sugaku); printf("英語:"); scanf("%d", &tanaka.eigo); printf("国語:"); scanf("%d", &tanaka.kokugo); struct test yamamoto; int yamamoto.sugaku, yamamoto.eigo, yamamoto.kokugo; strcpy(yamamoto.name, "Yamamoto"); printf("氏名:山本 三弘\n"); printf("数学:"); scanf("%d", &yamamoto.sugaku); printf("英語:"); scanf("%d", &yamamoto.eigo); printf("国語:"); scanf("%d", &yamamoto.kokugo); printf("数学の平均点は%dです。\n", ((suzuki.sugaku + tanaka.sugaku + yamamoto.sugaku) / 3.0)); printf("英語の平均点は%dです。\n", ((suzuki.eigo + tanaka.eigo + yamamoto.eigo) / 3.0)); printf("国語の平均点は%dです。\n", ((suzuki.kokugo, + tanaka.kokugo + yamamoto.kokugo) / 3.0)); return (0); } ================================================================