2014年01月08日

連続した配列の動的生成とFile I/O

アドレスの連続した配列のメモリ確保に躓いたのでメモ.
Vectorでやってもいいんですが,それだとFile I/O系を全て変更しないといけないので.


//Grobal
double3 **u_rms;
float3 ***u_timeAnime;

//複数subroutineを無理に一つにまとめたので,動かないかも
subroutine()
{
u_rms= new double3* [size1];
u_rms[0]= new double3 [size1* size2];
for(i= 1; i < size1; i++){ //Pointerを代入? 多分,要素アクセスのアドレス的な何か
u_rms[i]= u_rms[0] + (i* size2);
}
size_array_2D_d3= sizeof(double3)* size1* size2; //もしかしたら,Paddingが…

u_timeAnime= new float3** [is_1000];
u_timeAnime[0]= new float3* [is_1000* size1];
u_timeAnime[0][0]= new float3 [is_1000* size1* size2];
for( i= 0; i < is_1000; i++) { //[i][j]のために,i=0
u_timeAnime[i]= u_timeAnime[0]+ (i* size1);
for(j= 0; j < size1; j++){
u_timeAnime[i][j]= u_timeAnime[0][0]+ ((i* size1* size2)+ (j* size2));
}
}
size_array_3D_Anime_f3= sizeof(float3)* is_1000* size1*size2;



ofstream fout("rms.bin", ios_base::binary);
//先頭アドレスを文字列に変換するため.u_rmsは,ポインタで宣言しているため,並列の先頭要素のアドレスを.sizeof(u_rms)だと,ポインタの大きさを返す.
fout.write( (char*)(&u_rms[0][0]), size_array_2D_d3 );
fout.close();

fout.open("timeAnime.bin", ios_base::binary);
fout.write( (char*)(&u_timeAnime[0][0][0]), size_array_3D_Anime_f3d );
fout.close();

delete[] u_rms[0];
delete[] u_rms;
delete[] u_timeAnime[0][0];
delete[] u_timeAnime[0];
delete[] u_timeAnime;
}

posted by にゃんこ at 13:54| Comment(0) | TrackBack(0) | C++

2013年09月19日

Linux icpcとWin Intel composer

ご存じだと思いますが,Intel c++ compilerのLinux版は,アカデミック用途に限り無料なんですよね.
GCCとICPC(-fast?)を比較したら,2倍以上速くなったような記憶があります.-fast? -o2?オプション付けたからかもしれませんが.(最適化オプションをどうしたかはちょっと記憶無いです.)

開発はWin 7 32Bit,Visual studioで行ってます.

Winのインテルコンパイラ(コンポーザ?)では,exit()が通るのですが,
Linuxでは「error: identifier "exit" is undefined」だったようなメッセージで,通りません.

何ででしょう?

そんなわけで,
#ifndef _win32
#define exit(n) _exit(n)
#endif
みたいにしたら,どっちでも通るようになりました.わーい
posted by にゃんこ at 21:44| Comment(0) | TrackBack(0) | C++

2013年08月09日

配列とポインタ

よく間違える配列のポインタをメモ


int array[4][5]
「要素5個の配列」の要素4個の配列
1.int型要素20個が連続して確保されている
(2.Fortranとかでは配列要素外にアクセスできないはずだけど,C++ではポインタ的にアクセスできる.)

で,
&array:配列全体の先頭を示すポインタ
&array[0]:配列の先頭要素を示すポインタ.単にarrayと書いても良い(&array[0]に置き換えてくれる?)
array:&array[0]を示す場合もあれば,配列全体を示す場合も.
->sizeof(array) == sizeof(int)*4*5 != sizeof(&array[0])
この場合では,左2個は20B,右は4B.

なので,
int array[N][M];
...
sizeof(array);
としていたのを,

int **a= new int *[4];
for(i= 0; i < 4; i++){
a[i]= new int [5];
}
for(i= 0; i < 4; i++){
cout << a[i] << endl;//連続していないないよ
}

とすると,sizeof(a)はポインタの大きさを返す.

配列のアドレスが連続している必要性がある場合には,以下.

int (*b)[5]= new int [4][5];
for(i= 0; i < 4; i++){
cout << b[i] << endl;
for(j= 0; j < 5; j++){
b[i][j]= array0[i][j];
}
}
for( i= 0; i < 4; i++){
for(j= 0; j < 5; j++){
cout << b[i][j] << endl;
}
}
cout << sizeof(b) << endl;




使い道は分からないけど,
配列要素がアドレスに対して連続して確保されており,配列要素が範囲外でもポインタ的に動作するので,

int array0[4][5];
int i= 2, j= 3;
array0[i][j]= 23;
cout << array0[0][i*5+ j] << endl;

も一応できる.



for(i= 0; i < 4; i++){
cout << array0[i] << endl;
}

とすれば,sizeof(int)[B]*5=20B=x14づつアドレスが増えている.


配列を引数としても渡せる.が,ポインタを渡しているだけなので注意.
Privateメンバ変数なんかは無理かも?

for(i= 0; i < 4*5; i++){
array0[0][i]= i;
}
func(array0);
cout << array0[0][0] << endl;

void func(int (*a)[5])
{
cout << a[1] << endl;
for( int i= 0; i < 4; i++){
for(int j= 0; j < 5; j++){
cout << a[i][j] << endl;
a[i][j]++;
}
}
return;
}

ここで,aは「int型5個配列」の先頭を示すポインタ.int x[][5]としてもOK
posted by にゃんこ at 16:19| Comment(0) | C++