質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

91.01%

  • C

    3069questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

  • C++

    2928questions

    C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

  • Visual Studio

    1488questions

    Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

  • Visual C++

    99questions

    Microsoft Visual C++はWindowsのCとC++の統合開発環境(IDE)であり、コンパイラやデバッガを含んでいます。

タイマー関数を使いビットマップ形式で球を描画したいのだが、描画途中で描画されなくなる

受付中

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 201

TRON1216.

score 14

.bat形式のあるデータ(球体の半径など)を読み取り、タイマー関数を用いてビットマップ形式で描画しようとしています。ビルドも無事にでき、実行したのですが、なぜか途中でエラーが起きます。半径の全データ数は約4600個あり、150msごとに再描画を繰り返す感じです。エラーのタイミングはさまざまで、2422番目のデータでストップしたり、3355番目でストップなどです。デバッグして調べたところ、全データの読み込みはちゃんとできていて、インフォヘッダーで書いた中身が0になっていました。メモリの解放のタイミングがおかしいのでしょうか?もしおかしければ解放のタイミングを知りたいです。また、この原因がメモリの解放以外にありそうでしたらアドバイスいただきたいです。よろしくお願いいたします。開発環境は、Visual Studio 2015 C++です。なお、まだ初心者なので、説明不足や知識不足、理解不足があるかもしれません。ご了承ください。下記に、描画するコードを載せておきます。

#define _USE_MATH_DEFINES
#include <math.h>
#define ID_MYTIMER 1




typedef struct{
    HINSTANCE hi0;
    HWND hwin7;
    BYTE *lpBmpData;
    BITMAPINFOHEADER bmp_ih;
    char *fname;
    int fsize;
} IMG;

IMG g_img;

LRESULT CALLBACK WndProc_bitmap( HWND hWnd_bitmap, UINT msg, WPARAM wp, LPARAM lp )
{

    PAINTSTRUCT ps;
    HDC hdc, hdc_mem;
    HBITMAP hBmp;
    float x,y,z,r;
    int a, b, ab;
    float lam1,lam2,lam3;

    g_img.bmp_ih.biSize = sizeof(BITMAPINFOHEADER);
    g_img.bmp_ih.biWidth = 659/*674*/;
    g_img.bmp_ih.biHeight = -494/*532*/;
    g_img.bmp_ih.biPlanes = 1;
    g_img.bmp_ih.biBitCount = 32;
    g_img.bmp_ih.biCompression = BI_RGB;
    g_img.bmp_ih.biSizeImage = 659/*674*/ * 494/*532*/ * 4;
    g_img.bmp_ih.biXPelsPerMeter = 3704;
    g_img.bmp_ih.biYPelsPerMeter = 3704;
    g_img.bmp_ih.biClrUsed = 0;
    g_img.bmp_ih.biClrImportant = 0;

    g_img.lpBmpData = (BYTE *)malloc(659/*674*/*494/*532*/*4);








    switch (msg) {

    case WM_CREATE: //ウインドウが生成されたときに1度だけ通過
        //時間割り込みの発生タイミングを設定
        SetTimer(hWnd_bitmap, ID_MYTIMER, 150, NULL);
        break;

    case WM_TIMER:
       if (wp != ID_MYTIMER)
           return (DefWindowProc(hWnd_bitmap, msg, wp, lp));
        k +=1;
        InvalidateRect(hWnd_bitmap, NULL, FALSE);

        break;

    case WM_PAINT:
        hdc = BeginPaint(hWnd_bitmap, &ps);
        hdc_mem = CreateCompatibleDC( hdc );
        q = 0;
        p = 0;
        for ( a = 0; a < 494/*532*/; a++){
            for( b = 0; b < 659/*674*/; b++){
                ab = a*(659/*674*/*4) + b*4; //始めの項が行数、次の項が左から何ビット目かを表す。(blueの位置を決めている)

                if((b-329.5)*(b-329.5)+(a-494)*(a-494) <= (s[k]/4*1000000*329.5+0.5)*(s[k]/4*1000000*329.5+0.5)){
                    p = p+1.0; //円の内側のピクセル数の合計
                    x = b-329.5;
                    y = 494-a;
                    z = sqrtf(-(x*x)-(y*y)+(s[k]/4*1000000*329.5+0.5)*(s[k]/4*1000000*329.5+0.5));
                    r = sqrtf(x*x + y*y + z*z);


                        lam1 = (x*XSUNm_3[k] + y*YSUNm_3[k] + z*ZSUNm_3[k])/(r*SUN_MOON[k]); //太陽の方向との内積
                        lam2 = (x*XEARTHm_3[k] + y*YEARTHm_3[k] + z*ZEARTHm_3[k])/(r*EARTH_MOON[k]); //地球の方向との内積
                        lam3 = (x*XEQLm_3[k] + y*YEQLm_3[k] + z*ZEQLm_3[k])/(r*EQL_MOON[k]); //EQLの方向との内積

                         /*g_img.lpBmpData[ab] = 179*lam3;
                         g_img.lpBmpData[ab+1] = 179*lam3;
                         g_img.lpBmpData[ab+2] = 179*lam3;
                         g_img.lpBmpData[ab+3] = 0;*/



                        if(lam2>0){
                         g_img.lpBmpData[ab] = 230*lam2;
                         g_img.lpBmpData[ab+1] = 216*lam2;
                         g_img.lpBmpData[ab+2] = 0;
                         g_img.lpBmpData[ab+3] = 0;

                       }

                        if(lam1>0){
                         g_img.lpBmpData[ab] = 0;
                         g_img.lpBmpData[ab+1] = 255*lam1;
                         g_img.lpBmpData[ab+2] = 255*lam1;
                         g_img.lpBmpData[ab+3] = 0;
                       }

                        if(!(lam1>=0 || lam2>=0) ){
                         g_img.lpBmpData[ab] = 179*lam3;
                         g_img.lpBmpData[ab+1] = 179*lam3;
                         g_img.lpBmpData[ab+2] = 179*lam3;
                         g_img.lpBmpData[ab+3] = 0;

                         q = q+1;                
                        }

                 if(494 < (s[k]/4*1000000*329.5+0.5))
                     ok = q*100/325546;

                 if(494 >= (s[k]/4*1000000*329.5+0.5))
                    ok = q*100/p/*(M_PI* (s[k]/4*1000000*329.5+0.5)*(s[k]/4*1000000*329.5+0.5)/2)*/;

                }

                   // else{
                if((b-329.5)*(b-329.5)+(a-494)*(a-494) > (s[k]/4*1000000*329.5+0.5)*(s[k]/4*1000000*329.5+0.5)){
                        g_img.lpBmpData[ab] = 0;
                        g_img.lpBmpData[ab+1] = 0;
                        g_img.lpBmpData[ab+2] = 0;
                        g_img.lpBmpData[ab+3] = 0;
                       }


            }

        }

        hBmp = CreateDIBitmap(hdc, &(g_img.bmp_ih), CBM_INIT, g_img.lpBmpData, (BITMAPINFO *)(&(g_img.bmp_ih)), DIB_RGB_COLORS);
        free(g_img.lpBmpData);
        SelectObject(hdc_mem, hBmp);
        SetStretchBltMode(hdc, COLORONCOLOR);
        StretchBlt(hdc, 0, 0, 659/*674*/, 494/*532*/, hdc_mem, 0, 0, 659/*674*/, 494/*532*/, SRCCOPY);
        DeleteDC( hdc );
        DeleteDC( hdc_mem );
        DeleteObject( hBmp );
        EndPaint(hWnd_bitmap, &ps);
        ReleaseDC( hWnd_bitmap, hdc );

        break;
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

0

コンパイルしてないけど
mallocとフリーのタイミングが合ってないはずです。
下記ソースみたいにすればいいと思います

define _USE_MATH_DEFINES

include <math.h>

define ID_MYTIMER 1

typedef struct{
HINSTANCE hi0;
HWND hwin7;
BYTE *lpBmpData;
BITMAPINFOHEADER bmp_ih;
char *fname;
int fsize;
} IMG;

/*ここを消した*/
//IMG g_img;
/*ここを消した*/

LRESULT CALLBACK WndProc_bitmap( HWND hWnd_bitmap, UINT msg, WPARAM wp, LPARAM lp )
{

PAINTSTRUCT ps;
HDC hdc, hdc_mem;
HBITMAP hBmp;
float x,y,z,r;
int a, b, ab;
float lam1,lam2,lam3;

/*ここを消した*/
//  g_img.bmp_ih.biSize = sizeof(BITMAPINFOHEADER);
//  g_img.bmp_ih.biWidth = 659/*674*/;
//  g_img.bmp_ih.biHeight = -494/*532*/;
//  g_img.bmp_ih.biPlanes = 1;
//  g_img.bmp_ih.biBitCount = 32;
//  g_img.bmp_ih.biCompression = BI_RGB;
//  g_img.bmp_ih.biSizeImage = 659/*674*/ * 494/*532*/ * 
//  g_img.bmp_ih.biXPelsPerMeter = 3704;
//  g_img.bmp_ih.biYPelsPerMeter = 3704;
//  g_img.bmp_ih.biClrUsed = 0;
//  g_img.bmp_ih.biClrImportant = 0;
//  g_img.lpBmpData = (BYTE *)malloc(659/*674*/*494/*532*/*4);
/*ここを消した*/

switch (msg) {

case WM_CREATE: //ウインドウが生成されたときに1度だけ通過
//時間割り込みの発生タイミングを設定
SetTimer(hWnd_bitmap, ID_MYTIMER, 150, NULL);
break;

case WM_TIMER:
if (wp != ID_MYTIMER)
return (DefWindowProc(hWnd_bitmap, msg, wp, lp));
k +=1;
InvalidateRect(hWnd_bitmap, NULL, FALSE);

break;

case WM_PAINT:

/* ここに移動した */
IMG g_img;
g_img.bmp_ih.biSize = sizeof(BITMAPINFOHEADER);
g_img.bmp_ih.biWidth = 659/*674*/;
g_img.bmp_ih.biHeight = -494/*532*/;
g_img.bmp_ih.biPlanes = 1;
g_img.bmp_ih.biBitCount = 32;
g_img.bmp_ih.biCompression = BI_RGB;
g_img.bmp_ih.biSizeImage = 659/*674*/ * 494/*532*/ * 4;
g_img.bmp_ih.biXPelsPerMeter = 3704;
g_img.bmp_ih.biYPelsPerMeter = 3704;
g_img.bmp_ih.biClrUsed = 0;
g_img.bmp_ih.biClrImportant = 0;

g_img.lpBmpData = (BYTE *)malloc(659/*674*/*494/*532*/*4);
/* ここに移動した */

hdc = BeginPaint(hWnd_bitmap, &ps);
hdc_mem = CreateCompatibleDC( hdc );
q = 0;
p = 0;
for ( a = 0; a < 494/*532*/; a++){
for( b = 0; b < 659/*674*/; b++){
ab = a*(659/*674*/*4) + b*4; //始めの項が行数、次の項が左から何ビット目かを表す。(blueの位置を決めている)

if((b-329.5)*(b-329.5)+(a-494)*(a-494) <= (s[k]/4*1000000*329.5+0.5)*(s[k]/4*1000000*329.5+0.5)){
p = p+1.0; //円の内側のピクセル数の合計
x = b-329.5;
y = 494-a;
z = sqrtf(-(x*x)-(y*y)+(s[k]/4*1000000*329.5+0.5)*(s[k]/4*1000000*329.5+0.5));
r = sqrtf(x*x + y*y + z*z);

lam1 = (x*XSUNm_3[k] + y*YSUNm_3[k] + z*ZSUNm_3[k])/(r*SUN_MOON[k]); //太陽の方向との内積
lam2 = (x*XEARTHm_3[k] + y*YEARTHm_3[k] + z*ZEARTHm_3[k])/(r*EARTH_MOON[k]); //地球の方向との内積
lam3 = (x*XEQLm_3[k] + y*YEQLm_3[k] + z*ZEQLm_3[k])/(r*EQL_MOON[k]); //EQLの方向との内積

/*g_img.lpBmpData[ab] = 179*lam3;
g_img.lpBmpData[ab+1] = 179*lam3;
g_img.lpBmpData[ab+2] = 179*lam3;
g_img.lpBmpData[ab+3] = 0;*/

if(lam2>0){
g_img.lpBmpData[ab] = 230*lam2;
g_img.lpBmpData[ab+1] = 216*lam2;
g_img.lpBmpData[ab+2] = 0;
g_img.lpBmpData[ab+3] = 0;

}

if(lam1>0){
g_img.lpBmpData[ab] = 0;
g_img.lpBmpData[ab+1] = 255*lam1;
g_img.lpBmpData[ab+2] = 255*lam1;
g_img.lpBmpData[ab+3] = 0;
}

if(!(lam1>=0 || lam2>=0) ){
g_img.lpBmpData[ab] = 179*lam3;
g_img.lpBmpData[ab+1] = 179*lam3;
g_img.lpBmpData[ab+2] = 179*lam3;
g_img.lpBmpData[ab+3] = 0;

q = q+1;                
}

if(494 < (s[k]/4*1000000*329.5+0.5))
ok = q*100/325546;

if(494 >= (s[k]/4*1000000*329.5+0.5))
ok = q*100/p/*(M_PI* (s[k]/4*1000000*329.5+0.5)*(s[k]/4*1000000*329.5+0.5)/2)*/;

}

// else{
if((b-329.5)*(b-329.5)+(a-494)*(a-494) > (s[k]/4*1000000*329.5+0.5)*(s[k]/4*1000000*329.5+0.5)){
g_img.lpBmpData[ab] = 0;
g_img.lpBmpData[ab+1] = 0;
g_img.lpBmpData[ab+2] = 0;
g_img.lpBmpData[ab+3] = 0;
}

}

}

hBmp = CreateDIBitmap(hdc, &(g_img.bmp_ih), CBM_INIT, g_img.lpBmpData, (BITMAPINFO *)(&(g_img.bmp_ih)), DIB_RGB_COLORS);
free(g_img.lpBmpData);
SelectObject(hdc_mem, hBmp);
SetStretchBltMode(hdc, COLORONCOLOR);
StretchBlt(hdc, 0, 0, 659/*674*/, 494/*532*/, hdc_mem, 0, 0, 659/*674*/, 494/*532*/, SRCCOPY);
DeleteDC( hdc );
DeleteDC( hdc_mem );
DeleteObject( hBmp );
EndPaint(hWnd_bitmap, &ps);
ReleaseDC( hWnd_bitmap, hdc );

break;

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 91.01%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • C

    3069questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

  • C++

    2928questions

    C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

  • Visual Studio

    1488questions

    Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

  • Visual C++

    99questions

    Microsoft Visual C++はWindowsのCとC++の統合開発環境(IDE)であり、コンパイラやデバッガを含んでいます。

  • トップ
  • C++に関する質問
  • タイマー関数を使いビットマップ形式で球を描画したいのだが、描画途中で描画されなくなる