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

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

新規登録して質問してみよう
ただいま回答率
85.37%
C++

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

Q&A

解決済

1回答

10312閲覧

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

Tlllune

総合スコア15

C++

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

0グッド

0クリップ

投稿2019/01/19 11:16

編集2019/01/19 11:19

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(); //画面の更新 } }

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

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

投稿2019/01/20 08:55

Tlllune

総合スコア15

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.37%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問