dynamic allocation and polymorphism - c++ [closed] - c++

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 ...

Related

how to accessing vectors in a loop [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 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());
}

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).

Returning pointers that point to member data [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
Pseudocode, I don't know if this compiles or not, but you get the idea.
class DataHolder
{
void GetData(float* ptr)
{
ptr = dataNeededByOtherClass;
}
float* dataNeededByOtherClass; // Initialized and modified elsewhere
};
class DataUser
{
void DoStuff()
{
float* ptrToData;
dataHolder->GetData(ptrToData);
// ptrToData points to garbage Why?
ptrToData = dataHolder->dataNeededByOtherClass;
// ptrToData now points to the correct data
}
};
What am I looking at here?
The function
void GetData(float* ptr)
receives the pointer argument by value. Modifying ptr within the function does not change the value of ptrToData. Instead, try to pass a pointer by pointer:
void GetData(float** ptrptr)
{
*ptrptr = dataNeededByOtherClass;
}
float* ptrToData;
dataHolder->GetData(&ptr);
P.S. Please note that exposing class variables in such a way is not considered as best practice.
Hi there are several syntax errors in your code. The code below doesn't add constructors and destructors as you mention them in your text above. Your data needs to come from somewhere :) I took the libery of creating a SetData method below. Note that I also free the memory of your buffer in both the destructor and when you set the pointer, if the pointer is not null. If you don't want this just cut it away :)
Working Code
class DataHolder
{
private:
float* dataNeededByOtherClass; // Initialized and modified elsewhere
public:
float* GetData()
{
return dataNeededByOtherClass;
}
void SetData(float* ptr)
{
// Remove if you intend to keep this memory and release it elsewhere
if (dataNeededByOtherClass != NULL)
delete[] dataNeededByOtherClass;
dataNeededByOtherClass = ptr;
}
// You are missing constructors and destructors
DataHolder() : dataNeededByOtherClass(NULL){};
DataHolder(float *ptr) : dataNeededByOtherClass(ptr){};
~DataHolder()
{
// if you want to release data after class is destructed.. if not remove these lines
if (dataNeededByOtherClass != NULL)
delete[] dataNeededByOtherClass;
};
}
class DataUser
{
void DoStuff()
{
DataHolder dataHolder; // either feed data in c'tor or use dataHolder->SetData() for filling data, now it's just empty..
float* ptrToData = dataHolder.GetData();
}
};
Hope it helps.

Delete object inside the class C++ [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
There is a part of my class, which I'm using to read data, byte by byte, until '\0' occur.
RESULT MyClass::readMethod(DataInputStream& s)
{
if ( condition = ok )
{
char tmp[32];
uint8 i = 0;
do {
tmp[i] = s.read_int8();
} while (tmp[i++] == '\0');
char *arr= new char[i];
for (uint8 j = 0; j < i; ++j)
{
arr[j] = tmp[j];
}
//delete[] arr;
}
}
I removed a lot of code for this post, since rest is less important.
My problem is, that I want to free up memory, but since I've got method:
I tried put it into destructor:
MyClass::~MyClass()
{
delete [] arr;
}
but compiler (I use Visual Studio 2010) underline it and says: "Error: identifier arr is undefined".
I can't use it in place where it is commented, because I've got following method:
char * getArr()
{
return arr;
}
But tbh, I don't know if it will work, I mean, if I can access arr outside the class. Im still learning C++ and OOP, and sometimes I'm confused.
Similiar problem is with constructor: how to initialize arr to be empty.
Your arr is local to readMethod. So the destructor does not know it. You have to declare arr as a class member.
class MyClass
{
private:
char* arr;
}
Then you can delete it in your destructor.

Having run time error with "delete[]" [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
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.
Closed 8 years ago.
Improve this question
I was trying to program my own List class on C++.
Here is the code:
template <class T>
class List
{
private:
T *value, *valueHelper;
int valueSize;
public:
int size;
List()
{
valueSize = 2;
value = new T[valueSize];
size = 0;
}
void Add(T val)
{
size++;
if (size > valueSize)
{
valueSize *= 2;
valueHelper = new T[valueSize];
memcpy(valueHelper, value, sizeof(T) * (size - 1));
delete[](value);
value = valueHelper;
}
value[size - 1] = val;
}
void Clear()
{
delete[](value);
size = 0;
valueSize = 2;
value = new T[valueSize];
}
T & operator[](int P)
{
return value[P];
}
};
The problem appered when I used a class variable on this List Class.
When I do Clear to delete some memory, there are a run time error appers.
I have trying to check what cause this problem and I have find out that this line on the function Clear() is the error line:
delete[](value);
I can not understand, why?
I'm just guessing here, but it could be likely it is because you will have copies made of the List instance, for example by returning it from a function or passing it as a non-reference argument to a function.
Copying of objects are implemented by the default copy-constructor generated by the compiler, but it only does shallow copying, meaning it will copy the pointers but not what they point to. So then you will have two copies with pointers pointing to the same memory, and when one object deletes that memory the others pointer will be invalid.
You also have a memory leak in that you don't have a destructor, so when an instance goes out of scope then you loose the allocated memory forever.
You should also read about the rule of three.