how to accessing vectors in a loop [closed] - c++

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I am programming a Space Invaders clone and I am struggling at creating the bullets.
Whenever I click Space a bullet is supposed to be added to the vector and then I want to move them via a loop, but I dont understand how to create and handle it the proper way.
vector<Bullet> bullets(MAXBULLETS);
int bulletcounter = 0;
while (1) {
Sleep(10);
for (int i = 0; i < sizeof(bullets)-1; i++) {
bullets[i].Move(0, 1);
}
if (GetAsyncKeyState(VK_SPACE)) {
Bullet *bullet = new Bullet();
bullets[bulletcounter] = bullet; // Here is the error
bulletcounter++;
}

bullets is a vector that holds objects of type Bullet.
Bullet *bullet = new Bullet();
bullets[bulletcounter] = bullet; // Here is the error
Your bullet here is of type Bullet*. The two incompatible types get you the error.
To fix this, stop using a pointer and just instantiate an object:
Bullet bullet;
This creates a Bullet object using the parameterless constructor that you can then add to your bullets.
Do note though, that this currently does nothing since you initialize your vector giving it a predefined size bullets(MAXBULLETS), this already creates MAXBULLETS default constructed objects for you, ready to use:
Constructs the container with count default-inserted instances of T.
No copies are made.
Side note : stop using new altogether; this isn't Java or C#. If you need a dynamically allocated object then use a smart pointer. Most of the time, though, an object automatic-storage duration will do just fine.

My proposal
vector<Bullet> bullets;
while (1)
{
Sleep(10);
for (int i = 0; i < bullets.size(); i++)
{
bullets[i].Move(0, 1);
}
if (GetAsyncKeyState(VK_SPACE))
{
bullets.push_back(Bullet());
}

Related

Destructor that deallocate dynamically allocated char array [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
I need to write a destructor to deallocate the char array, but I always get this error message "pointer being freed was not allocated". It looks like I delete the location more than once, so I try to check if the char pointer is NULL, but it still doesn't work. Please help.
Note that: house object is a member data of another class.
class House {
private:
char * location;
public:
House();
~House();
House::House() {
location = NULL
}
int House::create_house(char init_location[100]) {
location = new char [strlen(init_location) + 1];
strcpy(location, init_location);
return 1;
}
House::~House() {
if (location) {
delete [] location;
location = NULL;
}
}
Edit: I added the constructor and the function showing how my location is allocated.
pointer being freed was not allocated
In the code you show indeed you do not allocate anything. location is just a pointer, there is nothing that could be deleted. You shall only call delete on a pointer to an instance that was acllocated via new.
Use a std::string instead, forget about new and delete and spend your time on the important things.
...
The question has been edited in the meanwhile. The posted code is still missing pieces that would be required to reproduce the error, and as I am unsure what exactly is left out too the only thing to add is that you are most likely violating the rule of 0/3/5. The reason mentioned above for the error is still the same: You are trying to delete something where there is nothing (or something that has already been deleted). And my suggestion is still the same: use std::string.

dynamic allocation and polymorphism - c++ [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
Need some insight on how to complete this last part of my Marina class. Any help would be greatly appreciated.
This is a big project I'm working on. I created a group of classes that are derived from a base class Boat using public inheritance. The Marina class represents the care of the boats in a Marina. The Marina class contains a fixed size array of pointers to Boat.
The function should place a new Boat into the Marina if there is room and each new boat must be dynamically allocated. The function should also ask the user what kind of boat they want and then add that kind to the next empty place in the array.
The error suggests that you forgot to include Boat.h (or anything defining class Boat) in your cpp file.
But anyway, code shown in question has some problems :
line _m[i] = NULL; is outside of the loop where i is declared and will raise an error - and I cannot imagine a reason to have it there ...
you create an uninitialized boat, and do not keep a pointer to it : how will you find and initialize it ?
You said that boats should be dynamically initialized, and that method _add_boat must be void. IMHO there are only two acceptable ways :
create the boat outside of the method and only use add_boat to put it in marina (throwing exception if marina if full) :
void Marina::_add_boat(Boat *boat)
{
for (unsigned i = 0; i < _num_boats; i++)
{
if (_m[i] == NULL)
_m[i] = boat;
return;
}
throw std::runtime_error("Marina full");
}
usage :
Boat b = new Boat();
marina._add_boat(b);
pass arguments to initialize boat
void Marina::_add_boat(int type, Owner& owner, ...) // arguments for Boat ctor
{
for (unsigned i = 0; i < _num_boats; i++)
{
if (_m[i] == NULL)
_m[i] = new Boat(type, owner, ...);
return;
}
throw std::runtime_error("Marina full");
}
Below is original answer left only because some interesting comments refere to it
Why not something like :
I assume you have an array of boats (Boat *) in the Marina of size _num_boats. An empty place is conventionnaly a NULL. It gives :
static const unsigned int _num_boats = 100; // the value you need or a constexpr
class Marina {
Boat * boats[_num_boats];
...
Boat * Marina::_add_boat() {
for (unsigned i=0; i<_num_boats; i++) {
if (boats[i] == NULL) {
boats[i] = new Boat();
return boats[i]; // returns dynamically created Boat if room in Marina
}
}
return NULL; // return NULL if Marina full
}
}
With this logic you set attributes of Boat after placing it in Marina ...

pointer being freed was not allocated (suspected due to double deletion) [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
Every time I try to delete an object in my array of pointers plantLayout[][], I get the error "pointer being freed was not allocated". I debugged it and realized that every time that I step into the ~Plant() destructor it goes into the malloc files and then back to the ~Plant() destructor, and then back into the malloc files, and then it gets that error. I am assuming that it is because of a double deletion error, but I can not seem to figure out where I am going wrong.
Below is the relevant code:
MainWindow.h: (relevant code)
const static int rows = 5;
const static int columns = 10;
Plant *plantLayout[rows][columns-1];
Plant *seedingPlant;
Plant.h
#ifndef PLANT_H
#define PLANT_H
#include <QString>
#include <QGraphicsPixmapItem>
#include <sun.h>
class Plant
{
public:
Plant();
int x, y;//top left corner of the plant's lawn piece
int width, height;//of lawn piece
int plant, cost, life, range, damage, splash, slow, bomb, sun, need, row, column;
static int statCost;
double rate, seeding;
QString name;
QGraphicsPixmapItem *icon;
QString file;
Sun sunObject;
bool active;
virtual void beginAttackingSequence();
virtual void explosion();
};
#endif // PLANT_H
Plant.cpp
Plant::Plant()
{
this->sun = 0;
this->active = false;
this->height = 60;
this->width = 60;
this->sunObject.onScreen = false;
}
void Plant::beginAttackingSequence(){
}
void Plant::explosion(){
}
I assign the set the seeding plant equal to a new SunFlower() which is a subclass of Plant
seedingPlant = new SunFlower();
and then later on I assign a certain element of the plantLayout[][] array to the seedingPlant.
plantLayout[r][c] = seedingPlant;
at later points in the program I reinitialize the seedingPlant to be another different subclass of the Plant.
if(plantLayout[r][c] != NULL){
delete plantLayout[r][c];
}
I checked if that element is equal to null, which is what lead me to believe that it was a double delete that was causing the error!
Any help would be greatly appreciated! Thanks in advance!
You don't have all of the code posted, but a few things I can suggest:
You mentioned that SunFlower is a subclass of Plant. If you have polymorphic inheritance, you always want to have a virtual destructor (see C++ FAQ 20.7 for more info). In your case, add the following to the Plant declaration:
virtual ~Plant();
and add an implementation for it in Plant.cpp:
Plant::~Plant()
{
}
You're checking for NULL before invoking delete. You do not need to do that (and it's considered bad style). delete plantLayout[r][c]; by itself is just fine. See C++ FAQ 16.8 for more info.
Ensure that plantLayout is initialized to 0. e.g., in the constructor for MainWindow, you'll probably want:
for (int r = 0; r < rows; ++r)
for (int c = 0; c < columns-1; ++c)
plantLayout[r][c] = NULL;
My suspicion is that the "pointer being freed was not allocated" error is due to you invoking delete plantLayout[r][c] when plantLayout[r][c] is uninitialized (so it may contain some seemingly random value).

Access elements of vector of pointers [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Closed 9 years ago.
Improve this question
I have a little complicated problem. I'll try to explain what I've done.
I have a big class, which has as class-members
Mat vidImg
vector<Mat*> *VideoBuffer;
unsigned int currentVideoFrame;
I also have a class method
void loadVideoInBuffer(int num)
{
VideoBuffer.clear();
currentVideoFrame = 0;
vidDev.open(ListVideos.at(num).absoluteFilePath().toStdString()); // open videofile
while(true)
{
if(vidDev.read(vidImg) == false) // read from file int vidImg object
break;
VideoBuffer.push_back(new Mat(vidImg)); // pushback into vector
}
ui->tbVideo->setEnabled(true);
}
In this I am loading some objects loaded from another file into the Videobuffer vector.
If I try to load it again from this vector in another class-member which I am assigning here:
void grabAndProcessFrameVideo() // reload and show loaded inage
{
if(vidFlag == true)
{
vidImg = Mat(*(VideoBuffer[currentVideoFrame])); // load from vector
currentVideoFrame++; // inc index for vector
imshow("img",vidImg); // show reloaded object in another window
}
}
The Mat Object and imshow function are from the opencv lib but I think that this doesn't really matter. My problem is, that it just shows the last image. If I try to access the buffervector directly in the loading function in this way
void EAMViewer::loadVideoInBuffer(int num)
{
ui->tbVideo->setDisabled(true);
VideoBuffer.clear();
currentVideoFrame = 0;
if(vidDev.open(ListVideos.at(num).absoluteFilePath().toStdString()) == false)
{
newLineInText(tr("no Device found"));
return;
}
while(true)
{
if(vidDev.read(vidImg) == false)
break;
VideoBuffer.push_back(new Mat(vidImg));
imshow("img",Mat(*(VideoBuffer)[currentVideoFrame]));
waitKey(30);
currentVideoFrame++;
}
currentVideoFrame = 0;
ui->tbVideo->setEnabled(true);
}
Then it shows me it as wanted. So I think that the vector Pointer constellation is problematical if I stay in scope.
My questions are now:
1. Why the program don't crash while grabbing and processing?
2. and what can i do, that it prevent deleting?
Thanks in advance,
Inge
The reason for why only the last frame is shown is that Mat is a reference-counted class. So when you do something like
Mat vidImg;
vidDev.read(vidImg);
Mat* a = new Mat(vidImg);
a and vidImg are pointing at the same image. So all your elements in your vector are all pointing to the same (last loaded) image. What you want to do is:
Mat a = vidImg.clone();
or in your case (removing the pointers too since they shouldn't be there :) )
vector<Mat> VideoBuffer;
VideoBuffer.push_back(vidImg.clone());
So:
Remove all pointers (shouldn't have them raw anyways), since Mat is already a "handle" type class
use the clone() method to copy the image data.
I believe it might be because you're dereferencing the vector which as you have it is a pointer to a vector and not a vector, rather than the element that it actually contains.
Maybe try changing
vector<Mat*> *VideoBuffer;
to
vector<Mat*> VideoBuffer;
I would also suggest using a vector of smart pointers rather than raw pointers because at the moment your code is leaking memory all over the place. If you stick with the raw pointers you ought to delete each element of the buffer vector before you clear it as clear alone won't deallocate the memory
You'll also need to change
imshow("img",Mat(*(VideoBuffer)[currentVideoFrame]));
to
imshow("img",Mat(*VideoBuffer[currentVideoFrame]));
in the lower while loop
Have you got any loop that calls grabAndProcessFrameVideo() so it shows you all the images?
Could it be that it's showing all your images but really fast so you can only see the last one? If so, add a pause like you have in loadVideoInBuffer() (waitKey(30);) and you should see all the images.

destructor is called continuesly [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 8 years ago.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Improve this question
I'm currently working on a game using OpenGL ES 2.0 on Android (in C++ using the NDK).
I have a class called "Drawable" which is my base class for drawing objects using OpenGL.
In the destructor of the class I have to clean up some buffers :
Drawable::~Drawable() {
LOGE("release");
releaseBuffers();
}
But the destructor is called endlessly (as in every loop of the thread), which messes up my drawing.
I'm kind of lost here and I could not find similar problems, so help is welcome!
Edit: Loop code is here : link
Edit2: I found one of the evil calls:
In my player class I have this call:
currentWeapon->draw(this);
to
void Weapon::draw(Player* p)
If I comment this, the spam is gone.
There are very few ways a destructor gets called:
1) You create an instance of Drawable on the stack, and it falls out of scope. If this is done in a tight loop, the object will fall out of scope and be destroyed at each iteration of the loop. For example:
for (size_t i = 0; i < 100; ++i)
{
Drawable d;
}
Here, 100 instances of Drawable will be created and destroyed, at the beginning and end of every loop.
2) You delete a dynamically-allocated Drawable:
for (size_t i = 0; i < 100; ++i)
{
Drawable* d = new Drawable;
delete drawable;
}
3) You call the destructor explicitly:
Drawable* b = new (buffer) Drawable;
b->~Drawable()
Note that #3 uses "placement new" and is highly unlikely.
Objects can be destroyed at suprising times when they are in a container such as a vector. Consider:
vector <Drawable> drawables;
for (size_t i = 0; i < 10000; ++i)
{
Drawable d;
drawables.push_back (d);
}
You will notice potentially many destructor calls when you run this code. When you push_back, a copy is potentially made and the original (d here) is destroyed. Also, when the vector reaches capacity it has to reallocate, which results in every item being copied again, and the originals destroyed.
Objects can also be destroyed at suprising time in the face of temporaries and unexpected copies. Consider:
void DoSomething (Drawable d)
{
}
int main()
{
Drawable d;
for (size_t i = 0; i < 1000; ++i)
{
DoSomething (d);
}
}
This is a naive example because the compiler will likely elide the temporaries in this case. But since DoSomething() takes a Drawable by-value a copy of the original could be made. Depending on other code, the compiler might not even be able to elide this copy.