как за раз удалить массив текстур SDL2 ?
| |
Alkosha | Дата: Суббота, 23 Августа 2014, 03:02 | Сообщение # 1 |
участник
Сейчас нет на сайте
| Текстуры объявлены следующим образом. SDL_Texture* texSpr[256]; Чтоб их удалить, нужно проходиться по массиву, тем более нужно ещё знать размер массива. Так как не всегда кол-во texSpr достигает значения 256. Думал вектором объявить , да вот столкнулся с проблемой при добавлении новых элементов массива (которые добавляются не всегда по порядку). А именно, не знаю как корректно прописать push_back в данной ситуации.
Сообщение отредактировал Alkosha - Суббота, 23 Августа 2014, 03:03 |
|
| |
MrFiring | Дата: Суббота, 23 Августа 2014, 08:14 | Сообщение # 2 |
был не раз
Сейчас нет на сайте
| Если чуть-чуть подумать можно сделать вывод,что незагруженная текстура не будет ничего делать с элементом массива так или запишет туда NULL? Можно сделать вот так: Код int Counter = 0;
for(int i = 0; i < 256;i++) { if(textSpr[i] == NULL) Counter++; } Таким образом можно получить кол-во загруженных элементов массива..Если я правильно понял то тебе это и было нужно
|
|
| |
-l33t-h4xx- | Дата: Суббота, 23 Августа 2014, 08:30 | Сообщение # 3 |
участник
Сейчас нет на сайте
| Цитата Alkosha ( ) тем более нужно ещё знать размер массива. Обычно в таком случае люди хранят размер массива в отдельной переменной, но, зная любовь славянского мужика к непредсказуемости, не буду этого советовать. Статический массив для динамический данных - ужасная идея, используй malloc или векторы/списки.
Цитата Alkosha ( ) не знаю как корректно прописать push_back в данной ситуации. Покажи нам, как ты пишешь. Так? Код std::vector <SDL_Texture*> texSpr; texSpr.push_back(SDL_CreateTextureFromSurface(/*аргументы по вкусу*/));
Как правильно задавать вопросы
Сообщение отредактировал -l33t-h4xx- - Суббота, 23 Августа 2014, 08:33 |
|
| |
MrFiring | Дата: Суббота, 23 Августа 2014, 08:37 | Сообщение # 4 |
был не раз
Сейчас нет на сайте
| Цитата -l33t-h4xx- ( ) Хочу также на всякий случай добавить, что "за раз" ничего никогда не удаляется. Так не бывает. Так-то да лучше попариться денёк...Но потом проблем не будет
Сообщение отредактировал MrFiring - Суббота, 23 Августа 2014, 08:40 |
|
| |
Alkosha | Дата: Суббота, 23 Августа 2014, 23:10 | Сообщение # 5 |
участник
Сейчас нет на сайте
| Цитата -l33t-h4xx- ( ) Покажи нам, как ты пишешь. Так?
ну пока у меня обычным массивом, а не вектором. Код SDL_Texture* texSpr[256]; texSpr[nomer_kadra] = IMG_LoadTexture(renderer, filename); Ни каких сюрфейсов.
Цитата -l33t-h4xx- ( ) Хочу также на всякий случай добавить, что "за раз" ничего никогда не удаляется. Так не бывает.
Ну тогда думаю проще будет всё же стандартным массивом и оставить, и очистку выполнять в цикле. Разница в отличии от вектора разве что будет только в этом. Цитата -l33t-h4xx- ( ) Обычно в таком случае люди хранят размер массива в отдельной переменной Ну и в выделении области памяти, конечно же.
Но правильным ли будет такое решение...не знаю даже.Добавлено (23.08.2014, 23:10) --------------------------------------------- И ещё вопросец по динамическому массиву. Вот объявлен он у меня так char **bitmap=new char *[64]; Пробую его удалить так delete[] collisMap.bitmap; - ничего не происходит. Как массив и его содержимое были так и остались на месте.
Сообщение отредактировал Alkosha - Суббота, 23 Августа 2014, 16:52 |
|
| |
goldsphere | Дата: Суббота, 23 Августа 2014, 23:29 | Сообщение # 6 |
заслуженный участник
Сейчас нет на сайте
| Alkosha, в цикле надо удалять for int i ... delete [] collisMap.bitmap[i];
ТК у тебя двухмерный массив. http://cppstudio.com/post/432/
FinderX - Android Аркада
|
|
| |
Alkosha | Дата: Воскресенье, 24 Августа 2014, 03:22 | Сообщение # 7 |
участник
Сейчас нет на сайте
| Цитата goldsphere ( ) ТК у тебя двухмерный массив. http://cppstudio.com/post/432/
Странно. // удаление двумерного динамического массива for (int count = 0; count < 2; count++) delete []ptrarray[count];
Но когда я у себя сделал for(int i=0;i<63;i++) delete[] collisMap.bitmap[i]; То получил удаление только первой строки...
Даже не первой строки, а лишь её части
Сообщение отредактировал Alkosha - Воскресенье, 24 Августа 2014, 03:29 |
|
| |
Lertmind | Дата: Воскресенье, 24 Августа 2014, 05:58 | Сообщение # 8 |
заслуженный участник
Сейчас нет на сайте
| Alkosha, там по ссылке код немного неправильный, надо после ещё удалить память для указателей float*. Код float **ptrarray = new float* [2]; for (int count = 0; count < 2; count++) ptrarray[count] = new float [5];
for (int count = 0; count < 2; count++) delete [] ptrarray[count]; delete [] ptrarray; *ptrarray = 0; И ты хотел написать: for(int i=0;i<64;i++) delete[] collisMap.bitmap[i];
Сообщение отредактировал Lertmind - Воскресенье, 24 Августа 2014, 05:59 |
|
| |
OpenGOO | Дата: Воскресенье, 24 Августа 2014, 12:34 | Сообщение # 9 |
почти ветеран
Сейчас нет на сайте
| Цитата Alkosha ( ) for(int i=0;i<63;i++) delete[] collisMap.bitmap[i]; Код for(int i=0;i<size;++i) { delete collisMap.bitmap[i]; }
delete[] collisMap.bitmap;
Еще как вариант можно использовать умные указатели, тогда можно будет удалить массив за раз
Еще один вариант набросал (не проверял)
Код class Texture { SDL_Texture* m_tex;
public: Texture() { m_tex = nullptr; }
~Texture() { if (m_tex) { SDL_DestroyTexture(m_tex); m_tex = nullptr; } } bool load(const std::string &filename, SDL_Renderer *renderer) { m_tex = IMG_LoadTexture(renderer, filename); return (m_tex != nullptr); } bool isNull() const { return (m_tex == nullptr); }
operator SDL_Texture*() { return m_tex; } private: Texture(const Texture &); Texture& operator=(const Texture &); };
Пример использования
Код Texture texSpr[256]; texSpr[nomer_kadra].load(filename, renderer);
SDL_RenderClear(renderer); SDL_RenderCopy(renderer, texSpr[nomer_kadra], NULL, NULL); SDL_RenderPresent(renderer);
SDL_Delay(2000);
Мои проекты: - Свободный и открытый клон World Of Goo - TrueEngine2D (2D игровой фреймворк основанный на FreeBASIC)
[GameMaker: Studio v1.4.9999]
Сообщение отредактировал OpenGOO - Воскресенье, 24 Августа 2014, 14:49 |
|
| |
Alkosha | Дата: Воскресенье, 24 Августа 2014, 14:26 | Сообщение # 10 |
участник
Сейчас нет на сайте
| Цитата OpenGOO ( ) Texture texSpr[256]; texSpr[nomer_kadra].load(filename, renderer);
У меня несколько иначе. У меня в одном объекте класса заключён массив текстур, а не на каждый объект класса по текстуре.
И я вот что думаю. Если уничтожить объект, то и указатели на текстуры должны уничтожиться. Следовательно, и память должна освободиться ?
|
|
| |
OpenGOO | Дата: Воскресенье, 24 Августа 2014, 14:38 | Сообщение # 11 |
почти ветеран
Сейчас нет на сайте
| Цитата Alkosha ( ) И я вот что думаю. Если уничтожить объект, то и указатели на текстуры должны уничтожиться. Следовательно, и память должна освободиться ? Это зависит от того что что ты в деструкторе объекта написал.
Мои проекты: - Свободный и открытый клон World Of Goo - TrueEngine2D (2D игровой фреймворк основанный на FreeBASIC)
[GameMaker: Studio v1.4.9999]
|
|
| |
-l33t-h4xx- | Дата: Понедельник, 25 Августа 2014, 19:00 | Сообщение # 12 |
участник
Сейчас нет на сайте
| Цитата Alkosha ( ) Следовательно, и память должна освободиться ? Смерть указателя не означает смерти памяти, на которую он указывал. Цитата Alkosha ( ) Как массив и его содержимое были так и остались на месте. "Удаление" памяти не означает её исчезновения: блок памяти просто помечается как свободный. Конечно, содержание массива поэтому и не исчезает. Цитата goldsphere ( ) ТК у тебя двухмерный массив. Массив указателей не обязательно означает двухмерный массив.
Вот. А о чём остальная тема, я уже не понимаю. Си надо учить, кароч.
Как правильно задавать вопросы
|
|
| |
Alkosha | Дата: Четверг, 28 Августа 2014, 09:55 | Сообщение # 13 |
участник
Сейчас нет на сайте
| C динамическим массивом и конструктором\деструктором разобрался.
Но вот как создать "в куче" массив определённого объекта ?
пробовал myObject *obj [255]= new myObject; (и так пробовал myObject *obj = new myObject[255];) Компилятор ругается (точное содержание его ругани не запомнил). Конструктор и деструктор в классе присутствует. Один объект создаётся\уничтожается корректно.
Заодно хотелось бы узнать, как этот массив потом дэстройнуть.
|
|
| |
Snake174 | Дата: Четверг, 28 Августа 2014, 10:07 | Сообщение # 14 |
участник
Сейчас нет на сайте
| Цитата Но вот как создать "в куче" массив определённого объекта ? Код myObject *obj[ 255 ];
obj[0] = new myObject(...); ... obj[ 254 ] = new myObject(...);
if (obj[0]) { delete obj[0]; obj[0] = 0; } ... if (obj[ 254 ]) { delete obj[ 254 ]; obj[ 254 ] = 0; }
Не следует обманывать инспектора Pipmak Assistant Love2D Exporter Love2D-Helpers Old Consoles Games
Сообщение отредактировал Snake174 - Четверг, 28 Августа 2014, 10:13 |
|
| |
Archido | Дата: Четверг, 28 Августа 2014, 15:51 | Сообщение # 15 |
Сэнсэй
Сейчас нет на сайте
| Alkosha Надо срочно читать Страуструпа
C++ - он особенный. С помощью него можно не только выстрелить себе в ногу, но и повеситься в пустой комнате:)
|
|
| |
Saitei | Дата: Четверг, 28 Августа 2014, 16:31 | Сообщение # 16 |
старожил
Сейчас нет на сайте
| Цитата Snake174 ( ) myObject *obj[ 255 ]; offtop: это же массив указателей, да?
|
|
| |
Alkosha | Дата: Четверг, 28 Августа 2014, 19:06 | Сообщение # 17 |
участник
Сейчас нет на сайте
| Цитата Snake174 ( ) myObject *obj[ 255 ];
obj[0] = new myObject(...);
вот тут на второй строке пишет Цитата E:\TURBO\platform3\main.cpp|808|error: 'tileTex' does not name a type|
(tileTex - это то же, что и в вашем примере obj)
|
|
| |
Snake174 | Дата: Пятница, 29 Августа 2014, 12:12 | Сообщение # 18 |
участник
Сейчас нет на сайте
| Цитата offtop: это же массив указателей, да? Ну да )
Цитата вот тут на второй строке пишет ... Больше кода!!!
Не следует обманывать инспектора Pipmak Assistant Love2D Exporter Love2D-Helpers Old Consoles Games
|
|
| |
Alkosha | Дата: Воскресенье, 31 Августа 2014, 10:24 | Сообщение # 19 |
участник
Сейчас нет на сайте
| Код class myTileTex { public: bool mirror=false; SDL_Rect rect; SDL_Texture * tex; myTileTex() { tex=nullptr; }; void load( char* filename ) { tex = IMG_LoadTexture(renderer, filename); SDL_QueryTexture(tex, NULL, NULL, &rect.w, &rect.h); } ~myTileTex() { if (tex) { SDL_DestroyTexture(tex); tex= nullptr; } } };
myTileTex *tileTex[ 255 ]; tileTex[0] = new myTileTex(); Добавлено (31.08.2014, 10:24) --------------------------------------------- Всё-таки вот такое объявление сработало. Код myTileTex *tileTex = new myTileTex[255];
Прога пашет норм, а вот по завершению, если выйти из неё - крашит.
ТайлТєкс взаимосвязан с классом лэйер. При загрузке Код layer1->SetTilePos(a,b,c); на лэйер (слой) добавляются тайлтэксы (картинки разного размера, так что тайлами их сложно назвать) Код class layer { int r=255,g=255,b=255; public: float far; int tilenum; SDL_Rect position[255]; int indextile[255]; layer() { tilenum=0; }
void RGB(int R,int G,int <img src="http://s12.ucoz.net/sm/1/cool.gif" border="0" align="absmiddle" alt="cool" /> { r=R;g=G;b=B; } void mirror() { tileTex[tilenum].mirror=true; }
void SetTilePos(int i,int x,int y) {
position[tilenum].x = x*32; // установка позиции тайлов position[tilenum].y = y*32;
indextile[tilenum]= i; tilenum++; }
void display(){
for(int i=0;i<tilenum; i++) {
SDL_Rect DestRb1; DestRb1.x = position[i].x-cum.x/far; DestRb1.y = position[i].y-cum.y;
DestRb1.w =(tileTex[indextile[i]].rect.w); DestRb1.h =(tileTex[indextile[i]].rect.h); if(DestRb1.x>0-DestRb1.w&&DestRb1.x<800){
int r1,g1,b1;
if(r>=256||g>=256||b>=256) { if(r>=256)int r1=r-255; else r1=0; if(g>=256)int g1=g-255; else g1=0; if(b>=256)int b1=b-255; else b1=0;
SDL_SetTextureColorMod(tileTex[indextile[i]].tex,r1,g1,b1); } else SDL_SetTextureColorMod(tileTex[indextile[i]].tex,0,0,0);
SDL_SetTextureBlendMode(tileTex[indextile[i]].tex,SDL_BLENDMODE_BLEND );
if(tileTex[i].mirror) { SDL_RendererFlip flip = SDL_FLIP_HORIZONTAL; SDL_RenderCopyEx(renderer, tileTex[indextile[i]].tex , NULL, &DestRb1, NULL, NULL, flip); }else SDL_RenderCopy(renderer, tileTex[indextile[i]].tex , NULL, &DestRb1);//маска
if(r>=256||g>=256||b>=256) { if(r>=256) r1=255; else r1=r; if(g>=256) g1=255; else g1=g; if(b>=256) b1=255; else b1=b; SDL_SetTextureColorMod(tileTex[indextile[i]].tex,r1,g1,b1); } else SDL_SetTextureColorMod(tileTex[indextile[i]].tex,r,g,b);
SDL_SetTextureBlendMode(tileTex[indextile[i]].tex,SDL_BLENDMODE_ADD );
if(tileTex[i].mirror) { SDL_RendererFlip flip = SDL_FLIP_HORIZONTAL; SDL_RenderCopyEx(renderer, tileTex[indextile[i]].tex , NULL, &DestRb1, NULL, NULL, flip); }else SDL_RenderCopy(renderer, tileTex[indextile[i]].tex, NULL, &DestRb1);
} } } ~layer() {
delete[] tileTex;
} };
layer *layer1= new layer; layer *layer2= new layer;
Код class myTileTex { public: bool mirror=false; SDL_Rect rect; SDL_Texture * tex; myTileTex() { tex=nullptr; }; void load( char* filename ) { tex = IMG_LoadTexture(renderer, filename); SDL_QueryTexture(tex, NULL, NULL, &rect.w, &rect.h); } ~myTileTex() { if (tex) { SDL_DestroyTexture(tex); tex= nullptr; } } };
myTileTex *tileTex = new myTileTex[255];
по завершению выполняю. Код delete [] layer1; delete [] layer2;
Прога стала крашить после того, как я сделал тайлтэкс и лэйер "в куче". До этого нормально завершало программу.
|
|
| |
-l33t-h4xx- | Дата: Воскресенье, 31 Августа 2014, 12:48 | Сообщение # 20 |
участник
Сейчас нет на сайте
| Alkosha, что-то не видно tileTex среди членов класса layer, тем не менее layer считает себя вправе уничтожать tileTex в своём деструкторе. Может, объяснить ему его права получше? А то layer1 удаляй tileTex, layer2 удаляй - в результате одна и та же память освобождается два раза. Я бы тоже покрашился от такого.
Как правильно задавать вопросы
Сообщение отредактировал -l33t-h4xx- - Воскресенье, 31 Августа 2014, 13:05 |
|
| |
|