動的に構造体配列をとりたい C言語

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
何がエラーなんだなんだ

動的に構造体配列をとりたい C言語

#1

投稿記事 by 何がエラーなんだなんだ » 3年前

下記のプログラムをコマンドプロンプトで実行すると

========================
0:d0=33 d1=33 d2=33 d3=33 p=00000021
0:d0=19 d1=19 d2=19 d3=19 p=00000013
0:d0=19 d1=19 d2=19 d3=19 p=00000013
========================
1:d0=33 d1=33 d2=33 d3=33 p=00000021
1:d0=19 d1=19 d2=19 d3=19 p=00000013
1:d0=19 d1=19 d2=19 d3=19 p=00000013

と表示したところで終了してしまい最後まで実行してくれません。
その理由が知りたいです。
動的に構造体配列をとり、それを関数に渡してその関数の中で構造体の中身を書き換え、戻したいです。また、戻したときには書き換えた値は反映していてほしいです。下記プログラムはfuncで中身を書き換えmainに戻しています。それとfreeのやり方はこれで正しいでしょうか?よろしくお願いします。

コード:

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
typedef struct{
	int d0;
	int d1;
	int d2;
	int d3;
}data_t;

data_t func(data_t* pData,int i){
	pData[i].d0 = 19;
	pData[i].d1 = 19;
	pData[i].d2 = 19;
	pData[i].d3 = 19;
	printf("%d:d0=%d d1=%d d2=%d d3=%d p=%p\n",i, pData[i].d0, pData[i].d1, pData[i].d2, pData[i].d3, pData[i]);
	return *pData;
}
int main(){
	data_t* pData;
	for(int i=0;i<10;i++){
	pData = (data_t*)malloc(sizeof(data_t));
	pData[i].d0 = 33;
	pData[i].d1 = 33;
	pData[i].d2 = 33;
	pData[i].d3 = 33;
	printf("========================\n");
	printf("%d:d0=%d d1=%d d2=%d d3=%d p=%p\n",i, pData[i].d0, pData[i].d1, pData[i].d2, pData[i].d3, pData[i]);
	*pData = func(pData,i);
	printf("%d:d0=%d d1=%d d2=%d d3=%d p=%p\n",i, pData[i].d0, pData[i].d1, pData[i].d2, pData[i].d3, pData[i]);
	}
	printf("========================\n");
	printf("========================\n");
	for(int j=0;j<10;j++){
	printf("d0=%d d1=%d d2=%d d3=%d p=%p\n", pData[j].d0, pData[j].d1, pData[j].d2, pData[j].d3, pData[j]);
	}
	free(pData);
	return 0;
}

アバター
あたっしゅ
記事: 664
登録日時: 13年前
住所: 東京23区
連絡を取る:

Re: 動的に構造体配列をとりたい C言語

#2

投稿記事 by あたっしゅ » 3年前

https://it-ojisan.tokyo/struct-func-argument/
[c言語]関数の引数に構造体を渡す場合の注意(サンプルコードあり) - ITを使っていこう(ja)

コード:

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
typedef struct{
	int d0;
	int d1;
	int d2;
	int d3;
} data_t;


void
func(data_t* pData,int i)
{
	pData[i].d0 = 19;
	pData[i].d1 = 19;
	pData[i].d2 = 19;
	pData[i].d3 = 19;
	printf("%d:d0=%d d1=%d d2=%d d3=%d p=%p\n",i, pData[i].d0, pData[i].d1, pData[i].d2, pData[i].d3, (void*)&pData[i]);
}


int 
main()
{
    const int MAX = 10;
	data_t* pData = (data_t*)malloc(sizeof(data_t)*MAX);

	for( int i=0; i<MAX; i++ ) {
	    pData[i].d0 = 33;
	    pData[i].d1 = 33;
	    pData[i].d2 = 33;
	    pData[i].d3 = 33;
	    printf("========================\n");
	    printf("%d:d0=%d d1=%d d2=%d d3=%d p=%p\n",i, pData[i].d0, pData[i].d1, pData[i].d2, pData[i].d3, (void*)&pData[i]);
	    func( pData,i );
    	printf("%d:d0=%d d1=%d d2=%d d3=%d p=%p\n",i, pData[i].d0, pData[i].d1, pData[i].d2, pData[i].d3, (void*)&pData[i]);
	}

	printf("========================\n");
	printf("========================\n");

	for(int j=0;j<MAX;j++){
    	printf("d0=%d d1=%d d2=%d d3=%d p=%p\n", pData[j].d0, pData[j].d1, pData[j].d2, pData[j].d3, (void*)&pData[j]);
	}
	
	free(pData);

	return 0;
}
VTuber:
東上☆海美☆(とうじょう・うみみ)
http://atassyu.php.xdomain.jp/vtuber/index.html
レスがついていないものを優先して、レスするみみ。時々、見当外れなレスしみみ。

中の人:
手提鞄あたッしュ、[MrAtassyu] 手提鞄屋魚有店
http://ameblo.jp/mratassyu/
Pixiv: 666303
Windows, Mac, Linux, Haiku, Raspbery Pi, Jetson Nano, 電子ブロック 持ち。

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: 動的に構造体配列をとりたい C言語

#3

投稿記事 by みけCAT » 3年前

pDataには1要素分しか確保されていないバッファへのポインタ
(またはmallocが失敗した場合NULL)が代入されているのに、
存在しない2~10要素目へのアクセスがあるため、未定義動作になります。
範囲外へのアクセスが具体的にどうして落ちるのに繋がるかは環境によりますが、
・ヒープの管理情報を破壊し、malloc()やfree()で不都合が出た
・OSの管理レベルで確保されていない場所にアクセスした
などが考えられます。
freeのやり方は、ループ内で10回mallocさせているのに対し、
最後の1回で確保したバッファしかfreeしていないので、正しくないです。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

何がエラーなんだなんだ

Re: 動的に構造体配列をとりたい C言語

#4

投稿記事 by 何がエラーなんだなんだ » 3年前

あたっしゅさん、みけCATさん回答ありがとうございます。
とても参考になり、解決してすっきりしました。m(*_ _)m

返信

“C言語何でも質問掲示板” へ戻る