• 締切済み

構造体へのポインタ

typedef struct str_tmp_t{ int a; char b; } str_tmp; void main() { str_tmp *str_info; str_info->a = 1; } とした場合、コンパイルエラーは出てはいないのですが、数値を代入している個所で落ちてしまいます。 これを回避するには単純にmallocしてfreeすれば良いのでしょうか? よろしくお願い致します。

みんなの回答

noname#3823
noname#3823
回答No.4

str_tmp *str_info の宣言はこのstr_tmp型データのアドレスを入れる場所をstr_infoという名前で確保しただけです。 今の段階でアドレスは不定(でたらめ)です。 アドレスが不定なのにデータを入れるのは間違いです。 親切なコンパイラだと代入した段階でoutでしょうね。 領域確保の関数にアドレスをもらってそのアドレスをstr_infoに入れましょう。 そうすれば初めて代入できます。

  • MovingWalk
  • ベストアンサー率43% (2233/5098)
回答No.3

原因は#1さんの通りでしょう。 でもなぜ、ポインタ変数を定義してるんでしょう? (実体はどこに入れるんでしょう) 素直に実体を定義すればいいんじゃないでしょうか。 void main() { str_tmp str_info; str_info.a = 1; }

  • furlong
  • ベストアンサー率50% (17/34)
回答No.2

本当にポインターを使う必要があるのですか。この場合、バグの素になりやすいmallocとfreeを持ち出さずに、次のような書き方をすれば良いと思います。 int sub (str_tmp *s); void main () { str_tmp str_info; str_info.a = 1; sub (&str_info); } 又は、 void main () { str_tmp str_info [1]; str_info->a = 1; sub (str_info); }

  • PAPA0427
  • ベストアンサー率22% (559/2488)
回答No.1

そりゃあ落ちるでしょう。 だって、宣言文だけで実際にポインタにアドレスが設定されてませんから。 ポインタでmallocしてから、代入してください。

関連するQ&A

  • 構造体型のポインタ変数を含む構造体

    struct seiseki_tag { Int32 math ; Int32 english ; Int32 science; } ; typedef struct seiseki_tag SEISEKI ; struct personal_tag { Char name ; Int32 num ; SEISEKI *sptr } : typedef struct personal_tag PERSONAL ; struct info_tag { PERSONAL person_info ; } ; typedef struct info_tag INFO ; たとえば、上記のように3つの構造体があり、PERSONAL構造体のメンバーに SEISEKI構造体の型を持つポインタ変数が含まれているような場合で、下記のように INFO型のポインタ変数からSEISEKI構造体のメンバーを参照する方法を教えてください。 PERSONAL構造体メンバーのnameやnumは INFO *info ; info->person_info.name ; info->person_info.num ; のように参照すると思いますが、sptrが示すSEISEKI構造体のメンバーへの アクセスができません。下記のように参照を試みたのですがコンパイルは 通るのですが、実際に参照できていませんでした。 INFO *info ; SEISEKI *seiseki ; seiseki = info->person_info.sptr ; seiseki->math ; 判りにくい説明で申し訳ありませんが、どなたか教えていただければと思います。 よろしくお願いいたします。

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

    #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での対象もアドレスを示していると思うのですが、 結果は値を表示しているのはなぜでしょうか?

  • ダブルポインタ?

    下記のような関数が存在し、 最終的には mainで宣言した変数 "a" にDataGetでコピーしたデータを mainで再び使用したいのですが、 下記の方法だとmainに何も帰ってきません。 (NULLのまま・・・) 下記の関数を使用しmainに上手くデータを 引き継ぐためにはどうすれば良いのでしょうか? void Mem(int nSize,void **ptr){ char *tmp; tmp = malloc(nSize); *ptr = tmp; } void DataGet(char *aa,char *a){ int nSize = 5; (void)Mem(nSize,(void **)&a); memcpy(a,aa,nSize); return; } void main(){ char aa[20]; char *a = 0x00; memset(aa,0x00,20); memcpy(aa,"test",4); (void)DataGet(aa,a); /* aデータをここから再び使いたい */ }

  • 構造体内のポインタのポインタについて

    ポインタを理解するために以下のようなテストプログラムを作りました。 test.h --- typedef struct i_info{ int i_id; char i_name[64]; } I_INFO; typedef struct j_info{ int j_id; char j_name[64]; } J_INFO; typedef struct k_info{ int k_id; char k_name[64]; } K_INFO; typedef struct info{ int id; char name[64]; I_INFO iinfo; J_INFO *jinfo; K_INFO **kinfo; } INFO; --- test.c --- 1 #include <stdlib.h> 2 #include <stdio.h> 3 #include "./test.h" 4 5 int main(int argc, char **argv) 6 { 7 INFO info; 8 J_INFO j; 9 K_INFO k; 10 K_INFO *pk=NULL; 11 12 memset (&info,NULL,sizeof(info)); 13 memset (&j,NULL,sizeof(j)); 14 memset (&k,NULL,sizeof(k)); 15 16 info.id = 1; 17 memcpy(info.name,"***",3); 18 19 info.iinfo.i_id = 2; 20 memcpy(info.iinfo.i_name,"*i*",3); 21 22 info.jinfo = &j; 23 j.j_id = 3; 24 memcpy(j.j_name,"*j*",3); 25 26 info.kinfo = &pk; 27 pk= &k; 28 k.k_id = 4; 29 memcpy(k.k_name,"*k*",3); 30 31 printf( "%d\n",info.id); 32 printf( "%s\n",info.name); 33 printf( "%d\n",info.iinfo.i_id); 34 printf( "%s\n",info.iinfo.i_name); 35 printf( "%d\n",info.jinfo->j_id); 36 printf( "%s\n",info.jinfo->j_name); 37 /* 38 printf( "%d\n",info.kinfo->k_id); 39 printf( "%s\n",info.kinfo->k_name); 40 */ 41 } --- 38,39行目をコメントアウトするとコンパイルは通るのですが、 そのままだとコンパイルエラーになります。 なぜいけないのでしょうか?理由を教えてください。

  • ポインタ型配列のポインタを構造体のポインタ変数に格納する方法教えて!_ver2

    int型の配列は構造体のポインタ型のint型変数にはキャストすればうまくコンパイルが通りますが、同じ方法でfloat型の配列は構造体のポインタ型のfloat型変数にはキャストしてポインタの値を入れてもうまくコンパイルできず困っています。ちなみにコンパイルエラーは「互換でない型変換」と表示されます。 返答のほど、よろしくお願いいたします。 #include<stdio.h> #include<malloc.h> float time[] ={2.2, 2.3, 2.4}; int time2[] ={2, 2, 2}; struct timelist{ float *time; int *time2; struct timelist *next; }*head; void main(void) { struct timelist *p; p = (struct timelist *)malloc(sizeof(struct timelist)); p -> time = (float *)time[0]; p -> time2 = (int *)time2[0]; printf("time = %f\n", p -> time); printf("time2 = %d\n", p -> time2); }

  • 構造体へのポインタ

    すみません、構造体へのポインタの配列の扱いに困っています。 下記ソースの struct list *hashtable[HASHSIZE]; の箇所をmain部に入れた場合の 他の関数内での使用の仕方が全くわかりません。 どのように修正すれば良いのでしょうか。 申し訳ありませんが教えてください。 --------------------- #include <stdio.h> #include <stdlib.h> #include <string.h> #define HASHSIZE 40 #define MAX_KW_LEN 256 #define NUM_KW 23 #define TRUE 1 #define FALSE 0 struct list {  char keyword[MAX_KW_LEN];  struct list *next;   /* 次の list へのポインタ */ }; struct list *hashtable[HASHSIZE]; /* ハッシュテーブル */ /* キーワード ( Cの予約語 ) */ static char kw[NUM_KW][MAX_KW_LEN] = {   "auto", "break", "double",   "enum", "char", "continue", "extern", "float", "for", "int",   "long", "register", "short", "signed", "static",   "struct", "typedef", "union", "unsigned", "return",   "void", "volatile", "while" }; int Hash(char *key); void InitHTable(void); int FindKeyWord(char *key); void ListKeyWord(void); void FreeKeyWord(void); int main(void); int Hash(char *key) {  int hashval = 0;  while (*key != '\0')   hashval += *key++;  return (hashval % HASHSIZE); } void InitHTable(void) {  int i;  struct list *p, *q;  int hashval;  for (i = 0; i < NUM_KW; i++) {   printf("%d\n",i);   if ((FindKeyWord(kw[i])) == FALSE) { /* 登録されていなかったら */             /* メモリを割り付ける */    if ((p = (struct list *)malloc(sizeof(struct list))) == NULL) {     fprintf(stderr, "メモリ不足です。\n");     exit(2);    }    strcpy((*p).keyword, kw[i]);    hashval = Hash(kw[i]);    /* ハッシュ値を求めて */        if (hashtable[hashval] == NULL) { /* 未登録なら */     hashtable[hashval] = p;  /* p の指すアドレスを登録 */     p->next = NULL;    /* リストの末尾に NULL を追加 */    }    else {        /* 既に登録していたら */     q = hashtable[hashval];     while (q->next != NULL) {  /* データがなくなるまで */      q = q->next;    /* リストをたどる */     }     q->next = p;     /* リストの末尾に p の指すアドレスを登録 */     p->next = NULL;    /* その末尾に NULL を追加 */    }   }  } } int FindKeyWord(char *key) {  struct list *p;  for (p = hashtable[Hash(key)]; p != NULL; p = p->next)   if (!strcmp(key, (*p).keyword))  /* 登録済みなら */    return (TRUE);     /* TRUE を返す */   return (FALSE);      /* 未登録ならFALSE を返す */ } void ListKeyWord(void) {  int i;  struct list *p;  for (i = 0; i < HASHSIZE; i++)   for (p = hashtable[i]; p != NULL; p = p->next) /* p が NULL でなければ */               /* ハッシュ値とキーワードを表示 */    printf("予約語:%s ハッシュ値:%d:\n", (*p).keyword, Hash((*p).keyword)); } /* malloc( ) で割り付けたメモリを解放 */ void FreeKeyWord(void) {  int i;  struct list *p, *q;  for (i = 0; i < HASHSIZE; i++)   for (p = hashtable[i]; p != NULL; ) { /* p が NULL でなければ */    q = p->next;      /* p->next を保存 */    free(p);       /* メモリを解放 */    p = q;        /* p->next を p に代入 */   } } int main(void) {  char word[MAX_KW_LEN];  int i;  InitHTable( );  ListKeyWord( );  for (i = 0; i < 4; i++) {   printf("Cの予約語を入力して下さい ");   fgets(word, 128, stdin);   if ((FindKeyWord(word)) == TRUE)    printf("%s は登録済みです。\n", word);   else    printf("%s は未登録です。\n", word);  }  FreeKeyWord( ); }

  • 文字列の構造体キャスト

    文字列を構造体にキャストした際に、メンバ変数は以下のようには、 取得できないのでしょうか? typedef struct { int year; /* 学年 */ int clas; /* クラス */ int number; /* 出席番号 */ char name[64]; /* 名前 */ } student; int main(void) { student *data=NULL; char c[] = "123456789012abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghij1234"; char* tmp; tmp = &c[0]; student_print(data, tmp); return 0; } void student_print(student *data, char *mkg) { void* buff = NULL;    buff = (student*)mkg; printf("[year]:%s\n", buff ->year);←ここ return; }

  • ポインタと構造体

    C言語初心者です。 下のコードはリスト構造のサンプルコードを元に自分で書き直そうとしているコードです。(なので、現時点では不完全なところ(例えばfreeしてないとか)があるのと、自分で理解出来ていない箇所があります。) 実行すると、8から3までの値が一応表示されるようになったですが、その過程の仕組みが自分でもよく理解出来ていません。 (1)tra *q = NULL; 通常、構造体のポインタを使用するときはq = &___のように他の構造体のアドレスを渡して使用出来るようにすると思いますが、ここではなぜ*qに、NULLを代入する必要があるのでしょうか。 (2)そのNULL状態のポインタqを関数printingdudeに突っ込んで結果的に8、7、6、、と出力されるまでの過程がよくわかりません。簡単に解説して頂けると助かります。(ちょっと雑な質問になってしまい申し訳ありません) typedef struct transcript{ int no; struct transcript *next; } tra; void printingdude(struct transcript *m); tra* noud(int v, tra* c); int main(){ tra *q = NULL; int i; for(i = 8; i>1; i--){ printingdude(q); q = noud(i, q); } return; } void printingdude(struct transcript *m){ if(m ==NULL) return; printf("%d\n", m->no); } tra* noud(int v, tra* c){ tra *a = (tra *) malloc(sizeof(tra)); a->no = v; a->next = c; return a; }

  • 構造体を型の異なる構造体に代入

    C言語初心者です。 今回の質問は入力された構造体のメンバのデータを型の異なる構造体に代入したいのですが、毎回コンパイラにおこられてしまいます(汗)具体的には typedef struct MSG{ longint type; int flg; int Dt[64]; }t_msg; このDt[64]を以下の構造体に代入します。 typedef struct SC_MSG{ char a; char b; short c; char d; char e; short f; }t_sc_msg; その際、異なる関数で処理するため、 main(){ foo(&t_msg); }; void foo(t_msg *pt_msgdt){ t_sc_msg = (*pt_msgdt+8); ココがエラーになってしまいます。 何か、根本的な間違いをおかしている気がします。 ご指導の方、宜しくお願いします。 ちなみにOSはLinuxでコンパイラーはgccです。

  • 構造体と配列の関係

    #include<stdio.h> typedef struct stat { char alph; int count; }Stat; int main(void) { Stat al[26]; al.alphにアルファベットaからzを、al.countを全て0とし、各アルファベットに対するカウントを取れるようにしたいのですが、どのように書けば良いでしょうか?

専門家に質問してみよう