ポインタを使って配列にアクセス – プログラミング – Home

ポインタを使って配列にアクセス
 
通知
すべてクリア

[解決済] ポインタを使って配列にアクセス


Nagai
 Nagai
(@Nagai)
ゲスト
結合: 18年前
投稿: 3
Topic starter  

MFC でプログラムを作成しています

複数のデータから画像を描写するプログラムを作っています
ドキュメントクラスで以下のデータを読み込んで
BYTE Data1[43500];
BYTE Data2[43500];
BYTE Data3[43500];
BYTE Data4[43500];
BYTE Data5[43500];
BYTE Data6[43500];
BYTE Data7[43500];
BYTE Data8[43500];

ビュークラスで
以下のようにドキュメントクラスからそれぞれのデータにアクセスして
画像を作成して表示していました

C******Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);

BYTE buf;

for(int i=0;i<43500;i++){
buf=pDoc->Data1[i];
画像作成とかの処理
}

for(int i=0;i<43500;i++){
buf=pDoc->Data2[i];
画像作成とかの処理
}

それぞれのデータの画像作成の処理が長くなって
ソースが見にくいので

それぞれのデータ用に クラスの追加 Generic クラスで

独自のData1クラス~Data8クラスを作成し データのポインタを渡して
ビットマップに描写して HDCを返す関数(HDC GDIDraw(HDC hdcBMP,BYTE *Data))を
それぞれのクラスに追加したのですが

HDC hdcBMP;
ビットマップ作成

hdcBMP=Data1GDI.GDIDraw(hdcBMP,pDoc->Data1);

hdcBMP=Data8GDI.GDIDraw(hdcBMP,pDoc->Data8);

5個目のData5を Data5用のクラスの関数内でData5の配列にアクセスするとエラーにな
ってしまいます

HDC Data5::GDIDraw(HDC hdcBMP,BYTE *Data)
{
BYTE buf;
for(i=0;i<43500;i++){
buf=Data[i];←でエラー
}

return hdcBMP;
}

ドキュメントでData5の読み込みは成功して配列に収納出来ているのに
ビュークラス→独自クラスを通して配列のポインタアクセスでエラー
になるのは、どうしてなのでしょう?
上記の様なポインタの受け渡しはいけないのでしょうか。
お教え願えないでしょうか、よろしくお願いします。


引用未解決
トピックタグ
いろは
 いろは
(@いろは)
ゲスト
結合: 21年前
投稿: 43
 

実現の方法が良いか悪いかは別として、、、

>上記の様なポインタの受け渡しはいけないのでしょうか。

ぱっと見た目のコードでは悪くなさそうですし、出来なくは無いはずです。
デバッガを使って原因を特定しましょう。


返信引用
さやぴ
 さやぴ
(@さやぴ)
ゲスト
結合: 18年前
投稿: 29
 

直接は関係ないと思いますが、気が付いた点として、
int i は、long iに変更した方が良いです。

int型は16bit(環境によって違いますが・・・。)なので、
32767までです。


返信引用
いろは
 いろは
(@いろは)
ゲスト
結合: 21年前
投稿: 43
 

あっ、、さやぴさんそれかも!

インクリメントを続けていって32767+1をしたときにiの値が負値になる。
でポインタの値がおかしくなる。


返信引用
Nagai
 Nagai
(@Nagai)
ゲスト
結合: 18年前
投稿: 3
Topic starter  

ご返信ありがとうございます。
実際データは300×145ピクセルデータ列
なので、
読み込みは以下のように書いていました。
表記のため簡略化しておりましたすみません
for(int x=0;x<300;x++){
for(int y=0;y<145;y++){
buf=Data[x+y*300];←でエラー
}
}

int を longに変更しても同様にデータにアクセス
するとプログラムがエラーで落ちてしまいます
他に、原因は考えられるでしょうか?

ちなみに上記の場合
int のx とyはint の範囲内ですが
xとyの計算結果は intの範囲を超える時、正常な数値
が得られない場合があるのでしょうか?


返信引用
tetrapod
 tetrapod
(@tetrapod)
ゲスト
結合: 21年前
投稿: 830
 

他CPU用コンパイラでは確かにint=16bitである可能性がありますが
今はVC++6やVS200xなどでMFCを使ってるのですよね?
それならばint=32bitですからオーバーフローはありえません。
32767+1は正しく32768になりますしx+y*300はあふれません。
デバッガで BYTE* Data;の値をチェックするなどしてみましょう。


返信引用
さやぴ
 さやぴ
(@さやぴ)
ゲスト
結合: 18年前
投稿: 29
 

ごめんなさい。前日の私の発言は間違いでした。
tetrapodさんのご指摘の通り、int=32bitでした。
今までVC++とかは、16bitだと思い込んでいました。
(intは環境によって変わるので、私は使わないので気が付きませんでした。)

その他では、メモリ確保は配列(静的確保)でしているのでしょうか?
もし、そうであれば、メモリが本当に確保されているのか気になります。
動的確保にして、戻り値で確保されているか確認されては如何でしょうか?

また、的はずれでしたら、ごめんなさい。^^;;;


返信引用
てんてく
 てんてく
(@てんてく)
ゲスト
結合: 20年前
投稿: 92
 

memset(Data1, 1, sizeof Data1);
...
memset(Data8, 8, sizeof Data8);
など、わかりやすいデータで埋めてデバッガで確認するのが早いでしょう。

ところで、
for(int x=0;x<300;x++){
for(int y=0;y<145;y++){
buf=Data[x+y*300];←でエラー
}
}

x+y*300 -> 145*300+x = 43500 + x
てバッファ足りてないですけど


返信引用
Ryo
 Ryo
(@Ryo)
ゲスト
結合: 23年前
投稿: 252
 

あまり詳しくないから間違ってるかもしれないけど

> for(int y=0;y<145;y++){

ループの条件式が y<145 
だから、x=145でfor{}内を処理することはないのでは?


返信引用
Nagai
 Nagai
(@Nagai)
ゲスト
結合: 18年前
投稿: 3
Topic starter  

返信ありがとうございます。
メモリーは配列で静的確保だったので
動的確保malloc()に変更しました。
メモリーも実際に使うよりも多めに確保し
NULLは返ってこなっかたのでメモリーは
大丈夫だと思います。

色々試したところ、

プログラム的にまったく一緒だと思うのですが
下記のように、同じ大きさの配列に詰め替えたところ
データを読み込めました。
問題は別のところかととも思うのですが、
読み込みをコメントアウトするの問題なく
動作するので、自分のPC(XP)が問題かもしれません。
(他のPCで機会があれば試したいのですが
しばらく、PCに触れられないので)
問題が分からないので非情に気持ち悪いのでが、
これで解決とさせていただきます。
ありがとうございました。

BYTE buf[43500];

for(i=0;i<300;i++){
  for(j=0;j<145;j++){
    buf[i+j*300]=Data[i+j*300];
  }
}

BYTE buf2;
for(int x=0;x<300;x++){
for(int y=0;y<145;y++){
buf2=buf[x+y*300];
}
}


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました