I have a question, i want to use my Heap array like "Heap[i].value=x" i have value and Heap array in private and i have in my constructor ,but when i want to use like "Heap[i].value" it says Intellisense "No members available". What should i do, i really stuck. Thanks.
In my header
class MPQ
{
private:
//const int ITEM_NOT_FOUND =-1;
int value;
int label;
int size;
int Currentsize;
int *Heap; //heap array
int*Location;
In my cpp my constructor is
MPQ::MPQ(int n)
{
value=0;
label=0;
size=n;
Heap=new int [n];
Location =new int [n];
for (int i=0;i<size;i++)
{
Heap[i]=-1;//ITEM_NOT_FOUND;
Location[i]=0;
}
Currentsize=0;
}
i want to use my Heap array like "Heap[i].value=x"
In that case, Heap cannot be an array of int because int does not have a member value. In fact, int does not have any members at all. To be able to use Heap like that, it must be an array of such objects that do have a member value.
Related
I build two classes, cell, and HashTable, I want to declare an array of cells as a hashTable class member.
I want to do it with primitive vars like int,chars, like I declare array of cars as a hashTable class member.
I tried to declare an array of cells in some ways :
1.
class HashTable{
public:
int size;
int numOfKeys;
Cell* table = new Cell[10];
int cars[4];
//static void resize(HashTable &ht);
static void reinsert(Cell* new_table, int new_size, Node<Player*> *data);
HashTable() : size(10), numOfKeys(0) {
table = new Cell[10];
}
2. class HashTable{
public:
int size;
int numOfKeys;
Cell* table = new Cell[10];
int cars[4];
//static void resize(HashTable &ht);
static void reinsert(Cell* new_table, int new_size, Node<Player*> *data);
HashTable() : size(10), numOfKeys(0),table(new Cell[10]) {
}
I try to declare it in the constructor but it doesn't work.
How am I supposed to define this array?
Thanks !
I don't see any error , but I can see the array of cars but not the array of table
class Cell
{
public:
AVLTree<Player*>* AllPlayers;
int treeSize;
Cell() : treeSize(0) {
AllPlayers = new AVLTree<Player*>();
}
~Cell(){
delete AllPlayers;
};
Cell(const Cell &sec) = default;
Cell &operator=(const Cell &sec) = default;
void reinsert(Player* pl)
{
treeSize++;
AllPlayers->root = AllPlayers->insert(AllPlayers->root, pl,NULL);
}
int insert(Player* pl)
{
if (!(AllPlayers->findNode(AllPlayers->root,pl)))
{
AllPlayers->root = AllPlayers->insert(AllPlayers->root,pl,NULL);
treeSize++;
return 0;
}
return -1;
}
int remove(Player* pl)
{
AllPlayers->root = AllPlayers->remove(AllPlayers->root,pl);
treeSize--;
return treeSize;
}
};
class HashTable{
public:
int size;
int numOfKeys;
Cell* table;
int cars[4];
//static void resize(HashTable &ht);
static void reinsert(Cell* new_table, int new_size, Node<Player*> *data);
HashTable() : size(10), numOfKeys(0) {
table = new Cell[10];
}
~HashTable() { delete[] table; }
Fear not! You have an array of ten Cells pointed at by table.
table is a pointer. It holds an address, nothing more. A pointer knows only where an object is (note that the object may have been subsequently destroyed, a pointer has no way of knowing, or the pointer may not have been initialized). If the object referenced to by the pointer is an array, the pointer has no way to know how many items are in the array. The IDE cannot show that there are ten items in the array pointed at by table because all it knows is the pointer and the pointer does not know. If you want the IDE to display what is in those ten Cells, you need to set up what are commonly called "watch expressions" for each subobject in the array or play games with casting to tell the watch expression how to interpret the object at the pointer.
cars is an array. Arrays represent the whole whole array. They know their size, their dimensions and all of the data in the array. The IDE can show you all of the items in the cars array because cars knows all that there is to know.
If you know you will always and forever have 10 Cells, get rid of the pointer and define an array. If you don't know the size, you'll have to live with what the IDE can show you.
Side note: Some IDEs are smart enough to interpret a std::vector and can display the objects in the std::vector. Consider using std::vector instead of a dynamic array where possible. Intelligent handing in IDEs is but a small benefit of std::vector.
Side note: When I say object, I mean it in the C++ definition of object, not in the OOP sense of an instance of a class.
I am trying to implement a stack using an array. This is what I have in my
header file.I plan to assign the value to maxsize in the constructor. However, i keep getting errors. How can i fix this?
class stack {
private:
const int maxsize;
int arrays[maxsize];
int top;
public:
stack();
void additem(int);
void print();
};
A good fix would be:
class stack
{
std::vector<int> arrays;
int top;
public:
stack(int maxsize) : arrays(maxsize), top(0) {}
};
This way, you do not have any possibility of memory management bugs; your class behaves properly when copied, moved, swapped, etc. and your code is very simple.
An alternative, with a minimal memory footprint would be:
class stack
{
std::unique_ptr<int[]> arrays;
int maxsize;
int top;
public:
stack(int maxsize) : arrays(new int[maxsize]), maxsize(maxsize), top(0) {}
};
This version is movable, but will give compile errors when copied (as opposed to some of the other suggestions to use raw pointer, which will compile successfully and then give memory corruption at runtime). To make this class copyable you'd need to write your own copy-constructor and copy-assignment operator.
C++ doesn't allow variable-length arrays. Instead of an array, you can use a pointer and dynamic allocation.
And to initialize a const member, you have to do it in the initializer list of the constructor.
class stack {
private:
const int maxsize;
int *arrays;
int top;
public:
stack(int max = 10) : maxsize(max) {
arrays = new int[max];
top = 0;
}
void additem(int);
void print();
};
See How to initialize a const field in constructor?
You'll also then need a destructor that does delete[] arrays;.
But rather than using a C-style array, you'd probably find it easier to use std::vector<int>. This doesn't require specifying a maximum length in the first place, it will expand as needed.
Of course, you could skip this whole exersize and use std::stack<int>.
If you want maxsize to always be 10, you could do something like this:
class stack {
private:
static const int maxsize = 10;
int arrays[maxsize];
...
Note that I've made maxsize static. It will be the same for all instances of stack and is defined at compile time. Thus you can use it as an array size.
If you want maxsize to be variable, then you'll need to use dynamic allocation:
class stack {
private:
const int maxsize;
int* arrays;
...
public:
stack(int maxsize) : maxsize(maxsize), arrays(0) {
arrays = new int[maxsize];
}
~stack() { delete[] arrays; }
...
Note here that you must delete the memory you dynamically allocate. The usual place to do that is the destructor. If you want to go this route, you could also just use a std::vector<int> and get rid of maxsize entirely. That frees you from having to do any manual memory management.
I have a class like this:
Class Attributes
{
Public:
float* data;
float* x;
float min_x;
float max_x;
~Attributes();
};
at some point in the main function I create this:
Attributes attr;
float* data =(float*)malloc(N*sizeof(float));
float* x =(float*)malloc(N*sizeof(float));
/* populate values of data and x */
attr.data = data;
attr.x = x;
Then I populate the values and do my operation.
Now I understand that since I am creating the object only on stack, I need not delete it.
But what I thought was that it will automatically delete only the member variables including the pointers inside the class but I have to explicitly free the memory allocated for using malloc for data and x
So I wrote the Class's destructor as
Attributes::~Attributes()
{
if(data!=NULL)
free(data);
if(x!=NULL)
free(x);
}
As expected, once the scope of attr expires, the destructor is called. but on execution of free I get this error:
*** Error in '~/Plot':double free or corruption (!prev): 0x0000000002a7e9d0 ***
Can anyone explain me what is the mistake I am doing?
You are probably copying attr somewhere.
Here is a (working, not fixing the issues others have mentioned in the comments) version of your question. It does not trigger any doublefree errors:
#include <cstdlib>
class Attributes
{
public:
float* data;
float* x;
float min_x;
float max_x;
~Attributes() {
if(data!=NULL)
free(data);
if(x!=NULL)
free(x);
}
};
int main(int argc, char** argv) {
int N = 100;
Attributes attr;
float* data =(float*)malloc(N*sizeof(float));
float* x =(float*)malloc(N*sizeof(float));
attr.data = data;
attr.x = x;
}
The point is: when you are copying attr (even implicitly), you are responsible to either
track the resource usage (two objects refering to the same memory)
or also copy the allocated resources (i.e. depending on your specific semantics you can either set the pointers to NULL in the (copy-)constructor or you allocate a new array upon construction (which means you need to carry along a length field also, seriously, you should use std::vector)
You could use a smart pointer library to take care of your specific problem.
Just use std::vector, something like:
class Attributes
{
public:
void resize(std::size_t size)
{
data.resize(size);
x.resize(x);
}
private:
std::vector<float> data;
std::vector<float> x;
float min_x;
float max_x;
};
I'm trying to assign a node to a pointer along an array of pointers but it keeps telling me that my array was not declared in the scope. I'm totally confused on how or why so any help would be greatly beneficial! Thanks for taking the time to respond!
#include <iostream>
#include "book.h"
using namespace std;
class bookstore
{
private:
int amount = 5;
int counting = 0;
public:
bookstore()
{
bookstore *store;
store = new book*[amount];
for(int i = 0; i < amount; i++)
{
store[i] = NULL;
}
}
~bookstore(){ delete[] store; }
void addbook(string a,string b, string c, string d, string e)
{
if (counting == amount)
{
cout<<"Full House!"<<endl;
return;
}
store[counting] = new book(a,b,c,d,e);
counting++;
}
void print()
{
for(int i = 0; i < amount; i++)
{
cout<<store[i]->name<<" "<<store[i]->publisher<<" "<<store[i]->year<<" "<<store[i]->price<<" "<<store[i]->category<<endl;
}
}
};
Your pointer store is local to the default constructor. It looks like you're after a data member. Furthermore, you seem to be after an array of pointers. If so, you need bookstore needs to be a pointer to pointer:
class bookstore
{
private:
bookstore** store; // or bookstore* store
int amount = 5;
int counting = 0;
and fix the constructor to use that:
bookstore()
{
store = new book*[amount]; // or store = new book[amount]
....
Note that your class is attempting to manage dynamically allocated resources, so you will need to take care of the copy constructor and assignment operators (either make the class non-copyable and non-assignable, or implement them. The defaults are not acceptable. See the rule of three.) If you are really using an array of dynamically allocated pointers, then you need to fix your destructor too. Currently, it only deletes the array, but not the objects pointed at by the pointers in it.
The better solution would be to use a class that manages the resources for you and has the desired semantics. It is easier to have each class handle a single responsibility.
If I declare an array on the heap, how can I get information about the array?
Here is my code:
class Wheel
{
public:
Wheel() : pressure(32)
{
ptrSize = new int(30);
}
Wheel(int s, int p) : pressure(p)
{
ptrSize = new int(s);
}
~Wheel()
{
delete ptrSize;
}
void pump(int amount)
{
pressure += amount;
}
int getSize()
{
return *ptrSize;
}
int getPressure()
{
return pressure;
}
private:
int *ptrSize;
int pressure;
};
If I have the following:
Wheel *carWheels[4];
*carWheels = new Wheel[4];
cout << carWheels[0].getPressure();
How can I get call the .getPressure() method on any instance in the array when it is on the heap?
Also, if I want to create an array of Wheel on the heap, yet use this constructor when creating the array on the heap:
Wheel(int s, int p)
How do I do this?
Wheel *carWheels[4];
is an array of pointers to Wheel, so you need to initialize it with new:
for ( int i = 0; i < sizeof(carWheels)/sizeof(carWheels[0]); ++i)
carWheels[i]=new Wheel(); // or any other c-tor like Wheel(int s, int p)
later you can access it like that:
carWheels[0]->getPressure();
size of array can be retrieved like above:
sizeof(carWheels)/sizeof(carWheels[0])
[edit - some more details]
If you want to stick to array you will need to pass its size on function call because arrays decays to pointers then. You might want to stay with following syntax:
void func (Wheel* (arr&)[4]){}
which I hope is correct, because I never use it, but better switch to std::vector.
Also with bare pointers in arrays you must remember to delete them at some point, also arrays does not protect you against exceptions - if any will happen you will stay with memory leaks.
Simple, replace
Wheel *carWheels[4];
with
std::vector<Wheel*> carWheels(4);
for ( int i = 0 ; i < 4 ; i++ )
carWheels[i] = new Wheel(4);
You seem to be confusing () and [], I suggest you look into that.
You do know that ptrSize = new int(30); doesn't create an array, right?
Like C, you will need to lug the array's element count around with your allocation.
This information is actually stored by the implementation in some cases, but not in a way which is accessible to you.
In C++, we favor types such as std::vector and std::array.
Other notes:
ptrSize = new int(30); << creates one int with a value of 30
How do I do this?
Wheel(int s, int p)
Typically, you would just use assignment if you have an existing element:
wheelsArray[0] = Wheel(1, 2);
because you will face difficulty creating an array with a non-default constructor.
and while we're at it:
std::vector<Wheel> wheels(4, Wheel(1, 2));
is all that is needed to create 4 Wheels if you use vector -- no new required. no delete required. plus, vector knows its size.