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

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

ただいまの
回答率

87.37%

[C++]<vector>.push_back()で実行後にエラーメッセージ(corrupted size vs. prev_size)

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 6,465

score 15

C++初心者です。SDL2を触っています。
SDL2が生ではすこし使いづらいので、自作のちょっとしたライブラリを作ろうとしていたところでのつっかえです。

概要

自分で作った構造体を入れるvectorにpush_back()を使って値を格納しようとすると、ちゃんと動作するのですが、
実行後に謎のエラーメッセージ(なのか?)がでます。

corrupted size vs. prev_size
中止 (コアダンプ)

ネットでサイトや記事もいくつか見て回ったのですが、「範囲外アクセスやメモリリーク等メモリ関連の異常」というところまでは判明したものの、詳しい内容や肝心の解決方法が見当たらず困っています。
(目的のプログラム自体ちゃんと動くので無視するのも手ですが...どうしても気になってしまいます。)

質問

以下の質問にできるだけ答えていただきたいです。

(1) どのようにすれば解決できると考えられますか?
(2) vectorに構造体を格納する事自体に問題はありますか?

ソースコード(抜粋)

原因と思われるpush_back()は下の方、最後あたりにあります。
ちなみにこのpush_back()を消すと、(push_backの機能しない範囲で)ちゃんと実行、終了されます。

struct tesdl_object{ //オブジェクト
    short type;
    dxy pos,siz;
    db z;
    RGB col;
    tesdl_object(short ntp=0,dxy nxy={0.0,0.0},db nz=0.0,dxy ns={1,1},RGB nc=RGB(0,0,0)){
        type=ntp;
        pos=nxy;
        z=nz;
        siz=ns;
        col=nc;
    }
    bool operator<(const tesdl_object& tso)const{
        return z<tso.z;
    }
};

struct tesdl_screen{ //スクリーン
    tesdl_object conf;
    vector<tesdl_object> objs;
    set<int> check;
    vector<vector<RGB>> table;

    tesdl_screen(dxy nxy={0,0},db nz=0.0,RGB nc=RGB(1,1,1)){
        conf.pos=nxy;
        conf.z=nz;
        conf.siz=tesdl_system_window;
        conf.col=nc;
        table=tesdl_system_basetable;
        clear();
    }

    void push(tesdl_object qobj){
        objs.push_back(qobj);                      // <-ココ!
    }
}

ソースコード(フル)

下手なコードで申し訳ないです。

core.cpp

#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#include <SDL/SDL_ttf.h>
#include <SDL/SDL_mixer.h>

#include <iostream>
#include <functional>
#include <vector>
#include <queue>
#include <cmath>
#include <algorithm>
#include <string>
#include <array>
#include <map>
#include <set>

using namespace std;

typedef double db;

SDL_Surface* mainSf;

db clamp1(db &a){
    a=min(1.0,max(0.0,a));
}

struct dxy{ //座標
    db x,y;
    int ix,iy;
    dxy(db qx=0,db qy=0){
        x=qx;y=qy;
        ix=x;iy=y;
    }

    bool operator<(const dxy& tso)const{
        return y<tso.y or (y==tso.y and x<tso.x);
    }

    dxy operator+(const dxy& tso)const{
        return dxy(x+tso.x,y+tso.y);
    }

    dxy operator-(const dxy& tso)const{
        return dxy(x-tso.x,y-tso.y);
    }

    dxy operator/(const db& tso)const{
        return dxy(x/tso,y/tso);
    }

};

struct RGB{ //色
    db r,g,b,a;
    RGB(db xr=1.0,db xg=1.0,db xb=1.0,db xa=1.0){
        r=xr;
        g=xg;
        b=xb;
        a=xa;
    }
    void clampColor(){
        clamp1(a);
        clamp1(r);
        clamp1(g);
        clamp1(b);
    }
};

RGB getRgb(dxy point);


void colAlpha(RGB &col,dxy point={0,0}){ //色を作る
    RGB qq=getRgb(point);

    col.clampColor();

    if(col.a!=1.0){
        col.r=(col.r-qq.r)*col.a+qq.r;
        col.g=(col.g-qq.g)*col.a+qq.g;
        col.b=(col.b-qq.b)*col.a+qq.b;
    }

}


Uint32 toSDLrgb(RGB col,dxy point={0,0}){ //RGBをSDL用に(Uint32へ)変換
    colAlpha(col,point);
    return SDL_MapRGB(mainSf->format,255*col.r,255*col.g,255*col.b);
}

dxy tesdl_system_window={400,400};

int tesdl_system_wait=16;

void tesdl_init(){ //初期化
    SDL_Init(SDL_INIT_VIDEO);
    SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY,SDL_DEFAULT_REPEAT_INTERVAL);
    mainSf=SDL_SetVideoMode(tesdl_system_window.x,tesdl_system_window.y,32,SDL_SWSURFACE|SDL_DOUBLEBUF);
}


RGB getRgb(dxy point){ //指定した座標の色を取得
    Uint32 pixel=*((Uint32*)mainSf->pixels+point.iy*mainSf->w+point.ix);
    Uint8 r,g,b;
    SDL_GetRGB(pixel,mainSf->format,&r,&g,&b);
    return RGB(db((pixel>>16)&0xff)/255.0,db((pixel>>8)&0xff)/255.0,db(pixel&0xff)/255.0);
}

bool pointIn(dxy point){ 
    return point.ix<0 or point.iy<0 or point.ix>tesdl_system_window.x-1 or point.iy>tesdl_system_window.y-1;
}



void putDot(dxy point,RGB col){ //ドットを打つ

    if(pointIn(point))return;  


    Uint32 pixel=toSDLrgb(col);

    int bpp=mainSf->format->BytesPerPixel;
    Uint8 *p=(Uint8*)mainSf->pixels+point.iy*mainSf->pitch+point.ix*bpp;
    *(Uint32*)p=pixel;
}

tesdl.cpp

#include "core.cpp"

const short
    tesdl_type_rect=0
;

const vector<vector<RGB>> tesdl_system_basetable=vector<vector<RGB>>(tesdl_system_window.y,vector<RGB>(tesdl_system_window.x,RGB(1,1,1,1)));


struct tesdl_object{ //オブジェクト
    short type;
    dxy pos,siz;
    db z;
    RGB col;
    tesdl_object(short ntp=0,dxy nxy={0.0,0.0},db nz=0.0,dxy ns={1,1},RGB nc=RGB(0,0,0)){
        type=ntp;
        pos=nxy;
        z=nz;
        siz=ns;
        col=nc;
    }

    bool operator<(const tesdl_object& tso)const{
        return z<tso.z;
    }
};

struct tesdl_screen{ //スクリーン
    tesdl_object conf;
    vector<tesdl_object> objs;
    set<int> check;
    vector<vector<RGB>> table;

    void clear(){
        check.clear();
        objs={};
        table=tesdl_system_basetable;
    }

    tesdl_screen(dxy nxy={0,0},db nz=0.0,RGB nc=RGB(1,1,1)){
        conf.pos=nxy;
        conf.z=nz;
        conf.siz=tesdl_system_window;
        conf.col=nc;
        table=tesdl_system_basetable;
        clear();
    }

    dxy pointIn(dxy point,db nz){
        dxy qxy;
        qxy.x=(point.x-conf.pos.x);
        qxy.y=(point.y-conf.pos.y);
        return qxy;
    }

    void push(tesdl_object qobj){
        objs.push_back(qobj);                      // <-ココ!
    }

    void setScreen(tesdl_object tso){
        switch(tso.type){
            case tesdl_type_rect:{
                dxy
                    sxy=pointIn(tso.pos-tso.siz/2,tso.z),
                    exy=pointIn(tso.pos+tso.siz/2,tso.z)
                ;

                for(db iy=sxy.y;iy<exy.y;iy++){
                    for(db ix=sxy.x;ix<exy.x;ix++){
                        check.insert(iy*conf.siz.ix+ix);
                        colAlpha(tso.col,{ix,iy});
                        table[iy][ix]=tso.col;
                    }
                }
                break;
            }
        }


    }

    void show(){

        SDL_FillRect(mainSf,0,toSDLrgb(conf.col));
        for(auto itr:objs)setScreen(itr);
        dxy ds;

        for(auto itr=check.begin();itr!=check.end();++itr){
            int it=*itr;
            ds=dxy(it%conf.siz.ix,it/conf.siz.ix);
            putDot(ds,table[ds.iy][ds.ix]);

        }

        clear();
        SDL_Flip(mainSf);
        SDL_Delay(tesdl_system_wait);

    }

};


main.cpp

#include "tesdl.cpp"

int main(){
    tesdl_system_window={400,400};
    tesdl_init();
    bool looping=true;
    SDL_Event ev;
    tesdl_screen sc;

    while(looping){

        //入力用ループ(今回の件については関係なし)
        while(SDL_PollEvent(&ev)){
            switch(ev.type){
                case SDL_QUIT:
                    looping=false;
                    break;
            }
        }

        sc.push(tesdl_object(0,{30,40},0,{64,16},RGB(0,0,0,1))); //オブジェクトを表示

        sc.show(); //画面の更新
    }
}
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

check解決した方法

0

(またもや自己解決ができてしまった...)
申し訳ないです、気のつかないどこかで<vector>[負数]が実行されようとしていたのが原因でした。
うっかりです。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

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

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

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