Allegro.cc Forums » Programming Questions » Pointers and arrays.

 Gnamra Member #12,503 January 2011 I've got a problem. Check the edit.#SelectExpand 1Obj objectArray[255]; 2Obj *activeObjects[255]; 3 if(doLogic && al_is_event_queue_empty(event_queue)){ 4 doLogic = false; 5 if(Input::mouse[1]) 6 { 7 8 Input::mouse[1] = false; 9 for(int i = 0; i < 80; i++) 10 { 11 float r2 = (float)rand()/((float)RAND_MAX/ALLEGRO_PI*4); 12 objectArray[nextStartingIndex].lifespan = 4; 13 objectArray[nextStartingIndex].rotation = r2; 14 objectArray[nextStartingIndex].velX = -2 + (4 * (rand()/(RAND_MAX + 1.0))); 15 objectArray[nextStartingIndex].velY = -3 + (4 * (rand()/(RAND_MAX + 1.0))); 16 objectArray[nextStartingIndex].x = Input::mouseX; 17 objectArray[nextStartingIndex].y = Input::mouseY; 18 activeObjects[nextStartingIndex] = &objectArray[nextStartingIndex]; 19 nextStartingIndex++; 20 activeObjectsCount++; 21 if(nextStartingIndex >= 255) nextStartingIndex = 0; 22 } 23 } 24 25 for(int i = 0; i < activeObjectsCount; i++) 26 { 27 activeObjects[i]->lifespan--; 28 activeObjects[i]->velY += gravity; 29 activeObjects[i]->x += activeObjects[i]->velX; 30 activeObjects[i]->y += activeObjects[i]->velY; 31 } 32 } (I know that the activeObjectsCount isn't being decremented so it'll just increase to beyond 255 and cause out of bounds.)I've tried a couple of different ways to deal with the pointers in the activeObjects array.I want to do it this way because having a list of pointers referencing the active objects in the objectArray eliminates the need to loop through the entire objectArray.I clearly don't understand enough about pointers and / or arrays. I've tried to delete the element, I've found that doesn't make sense since it's not a dynamic array.Could I do this with an array of Obj pointers? I've tried making a dynamic array of object pointers but the compiler kept complaining at me in every way I tried to do it. except if I did:```Obj *activeObjects; activeObjects = new Obj; ``` but that doesn't make sense to me. it points at directly to a new object not it's address? What?I do realize that I could do this with one of the standard containers, but I want to do it with arrays for educational reasons.Also, I'm sorry if I explained it badly. It's 9 am and I haven't slept yet, and I'm sick on top of that.Edit: After some more research, it seems like what I want to do is impossible? I'd have to create a new pointer array and copy the elements every time I wanted to add or remove elements? Guess I've got to switch to lists then.#SelectExpand 1 2if(doLogic && al_is_event_queue_empty(event_queue)){ 3 doLogic = false; 4 if(Input::mouse[1]) 5 { 6 7 Input::mouse[1] = false; 8 for(int i = 0; i < 80; i++) 9 { 10 float r2 = (float)rand()/((float)RAND_MAX/ALLEGRO_PI*4); 11 objList.push_back(Obj()); 12 objList.back().lifespan = 160; 13 objList.back().rotation = r2; 14 objList.back().velX = -2 + (4 * (rand()/(RAND_MAX + 1.0))); 15 objList.back().velY = -3 + (4 * (rand()/(RAND_MAX + 1.0))); 16 objList.back().x = Input::mouseX; 17 objList.back().y = Input::mouseY; 18 pObjList.push_back(&objList.back()); 19 nextStartingIndex++; 20 } 21 } 22 23 for(auto it = pObjList.begin(); it != pObjList.end();) 24 { 25 (*it)->lifespan--; 26 (*it)->velY += gravity; 27 (*it)->x += (*it)->velX; 28 (*it)->y += (*it)->velY; 29 if((*it)->lifespan <= 0) 30 { 31 it = pObjList.erase(it); 32 }else it++; 33 } 34 } 35 36 37 if(redraw && al_is_event_queue_empty(event_queue)) 38 { 39 redraw = false; 40 41 for(auto it = pObjList.begin(); it != pObjList.end(); 42 { 43 al_identity_transform(&transform); 44 al_translate_transform(&transform, -(*it)->x+5, -(*it)->y+5); 45 al_scale_transform(&transform, 2, 2); 46 al_rotate_transform(&transform, ALLEGRO_PI*1.5); 47 al_translate_transform(&transform, (*it)->x+5, (*it)->y+5); 48 al_use_transform(&transform); 49 al_draw_rectangle((*it)->x, (*it)->y, (*it)->x+10, (*it)->y+10, al_map_rgb(255,255,255), 2); 50 } 51 al_flip_display(); 52 } is what I'm doing here terribly expensive / ineffective? cause I was running debug with 1 std::cout in one of the for loops and the fps was roughly 5.Removing the std::cout fixed the fps, but I'm still concerned. Switching transforms like that, does that cost a lot? Also, my rectangles are scaling but not rotating? I know all of them are in use, so the second list is not needed and is slowing down my program but only a small part of them will be in use later on.
 l j Member #10,584 January 2009 (stl) Lists are quite slow, but they shouldn't drop your fps that low.Arrays are the fastest solution, albeit not the most dynamic.To create an array of pointers this is the syntax you should use: ```Obj **activeObjects; activeObjects = newObj*[length]; ``` An easy and fast way to remove an object using a collection like a vector is by moving the element to the back and then removing the last element.This won't preserve the order, but it's quite fast. It can even be done using a simple array, although it won't automatically handle resizing in case the container is too small.edit: fixed grammar errors, in both my post and code.
 bamccaig Member #7,536 July 2006 Rather than starting a thread with a big[, ugly] code block you should first describe what you're trying to do, why, and what the thread is about (i.e., what you want to discuss or need help with).Second, you should be try to be disciplined with your code. Every space, tab, brace or semi-colon should be intentional. We don't want to read through code that jumps around like this:Gnamra said: ```Obj objectArray[255]; Obj *activeObjects[255]; if(doLogic && al_is_event_queue_empty(event_queue)){ doLogic = false; if(Input::mouse[1]) ``` If you're concerned about performance then something like this doesn't make sense:Gnamra said: ```objList.push_back(Obj()); objList.back().lifespan = 160; objList.back().rotation = r2; objList.back().velX = -2 + (4 * (rand()/(RAND_MAX + 1.0))); objList.back().velY = -3 + (4 * (rand()/(RAND_MAX + 1.0))); objList.back().x = Input::mouseX; objList.back().y = Input::mouseY; ``` You are needlessly invoking std::list::back repeatedly. It makes better sense to create the object first and push it into the list afterward.```Obj obj; obj.lifespan = 160; obj.rotation = r2; obj.velX = -2 + (4 * (rand()/(RAND_MAX + 1.0))); obj.velY = -3 + (4 * (rand()/(RAND_MAX + 1.0))); obj.x = Input::mouseX; obj.y = Input::mouseY; objList.push_back(obj); ``` That said, taking the address of an std::list element is also probably wrong and dangerous. If you want pointers to things then you need to be in control of the pointers. You could use operator new to allocate your objects and store their pointers in your collections instead. You should use smart pointers to help with that to avoid memory leaks or ugly and error-prone cleanup code.Yes, the STL containers allocate new buffers when they run out of space. It's good for you to practice this yourself for educational purposes, but should encapsulate the functionality into an object, just as the STL does. You don't want to be manually manipulating these low-level arrays everywhere. You want to put that in a single place and reuse it. It's hard to get right and you only want to have to get it right one time. -- I mean the best with what I say. It doesn't always sound that way.