検索
[C]関数から返したアドレスを後から参照すると値がおかしい
- M.R

- 2023年1月2日
- 読了時間: 1分
現象
C言語で関数(func_a)を作成。引数の内容をもとにある構造体のインスタンスを作成し、そのアドレスを返す。
そのアドレスはその後別の関数(func_b)の引数に使用。アドレスを参照し、func_aで作成した構造体の内容をもとに規定の処理を行う。
typedef struct {
int a;
int b;
}SAMPLE_STRUCT
SAMPLE_STRUCT* func_a(int a, int b){
SAMPLE_STRUCT s;
s.a = a;
s.b = b;
return &s;
}
void func_b(SAMPLE_STRUCT *smpl){
int a =(*smpl).a; //aの値がおかしい
}func_bでメンバaの値を取り出すと、func_aで設定したのと異なる値が入っている。
問題:上記コードでどこがおかしいでしょう?
原因
答え:関数(func_a)のローカル変数として確保したアドレスを返しているから。
関数のローカル変数はスタックに取られる。そのアドレスを後から参照しても、スタックは別の関数でも使われているから、そのアドレスに格納されている値は順次変更される。
解決策
1 構造体そのものを返す
2 mallocなどでヒープに確保した変数のアドレスを返す
3 グローバル変数として確保した変数のアドレスを返す
SAMPLE_STRUCT* func_a(int a, int b){
SAMPLE_STRUCT *s =
(SAMPLE_STRUCT *)malloc(sizeof(SAMPLE_STRUCT));
s->a = a;
s->b = b;
return s;
}最後に
メモリをちゃんと理解していないとこういうミスが起こるんですね
![[C]動的リンクとは](https://static.wixstatic.com/media/90b712_18dcd348ceaf4fea8585e60a08091a5f~mv2.png/v1/fill/w_980,h_538,al_c,q_90,usm_0.66_1.00_0.01,enc_avif,quality_auto/90b712_18dcd348ceaf4fea8585e60a08091a5f~mv2.png)






コメント