How can I create memory management with a char array? - c++

I have to create a memory management program using a char array. The code I need to edit is as follows:
char mem[65536];
void initialize(void){
// TODO
}
void* allocate(int Size){
// TODO
return ((void*) 0);
}
void deallocate(void* Pointer){
// TODO
}
// scan the memory returning the total free space
int free(void){
// TODO
return 0;
}
I am currently trying to use structs and store them in the char array, but that doesn't seem to be working out. The struct I am using is:
typedef struct Node{
int size;
int free;
struct Node *next;
struct Node *prev;
}Node;
I try to find the memory for the struct by:
Node *start = &mem;
Is there an error in the struct implementation, or should I be implementing something other than a struct to manage this?
EDIT:
Restrictions:
I have to store all data in the char array mem.
No global variables other than mem is allowed.

Related

Is this a correct destructor for my Node struct?

I have this C++ struct:
struct Node {
char symbol;
unsigned int index;
vector<Node*> next;
// Constructors
Node():symbol('$'), index(0), next(0) {}
Node(char &c, const unsigned int &ind):symbol(c), index(ind), next(0) {}
// Add a new character
Node* add(char &c, const unsigned int &num) {
Node *newChar = new Node(c, num);
next.push_back(newChar);
return newChar;
}
// Destructor
~Node() {
for (int i = 0; i < next.size(); i++)
delete next[i];
}
};
(I know it might be better to make it a class but let's consider it as it is).
I'm not quite sure if I wrote the correct destructor for this. In the main function I'm using a root node:
Node *root = new Node();
Although the code won't leak memory (as long as you delete the root node in main), it isn't really optimal.
You should avoid new and delete and instead prefer smart pointers. In this case, use unique_ptr.
Also, don't create the root node on the heap, just create it normally like so:
Node root;
// use root normally
You also don't follow the rule of five properly, and you won't even need to worry about it if you used unique_ptr since you wouldn't have a custom dtor. There's also no reason to take the c and ind by ref and const ref, just pass them by value (because you don't even change them, and its as cheap passing by value as by ref for primitives).
With these changes, the code looks like this
struct Node {
char symbol;
unsigned int index;
vector<std::unique_ptr<Node>> next;
// Constructors
Node():symbol('$'), index(0){}
Node(char c, unsigned int ind):symbol(c), index(ind) {}
// Add a new character
Node* add(char c, unsigned int num) {
next.push_back(std::make_unique<Node>(c, num));
return next.back().get();
}
};

How to free a pointer to a vector storing pointers to a struct

struct node {
std::vector<struct node*> * list;
}
int main() {
struct node * n = new struct node;
n->list = new std::vector<struct node*>();
n->list->push_back(n);
return 0;
}
How can I delete the n->list with freeing all the pointers that the list is storing?
Will it be n->list->clear()? Or do I have to traverse n->list and call delete or free operator on each element in the list.
std::vector does not assume ownership of dynamically created objects.
(Even if it wanted to, or you created a specialisation or your own implementation, it's impossible to distinguish dynamic allocations from other pointers.)
You need to traverse the vector and free the elements.
The safer/simpler would be
struct node {
std::vector<node> list;
};
int main() {
node n;
n.list.resize(1);
}
or if you need pointer:
struct node {
std::vector<std::unique_ptr<node>> list;
};
int main() {
node n;
n.list.push_back(std::make_unique<node>());
}
First of all: you don't need so much pointers.
If you want it be be this way, you should delete it exactly the same way you have 'newed' it :).
In your example:
int main() {
struct node * n = new struct node;
n->list = new std::vector<struct node*>();
n->list->push_back(n);
delete n->list; // here's the change
delete n; // another required delete
return 0;
}
But as I said, too much news.
You can write your struct node as:
struct node {
std::vector<struct node*> list;
}
it will cause the list to be automatically deleted when node object is being deleted.
This line: struct node * n = new struct node; also can be converted into:
node n;

convert malloc to new c++ for struct

I have this struct:
struct problem
{
int length;
struct node **x;
};
and I created a struct of this struct like this:
struct problem prob;
I can do this in C:
prob.x = Malloc(struct node *,prob.length);
but how I can do it in c++ style with new ? and why ?
In C++, it would be achieved with this.
std::vector<node *> problem(length);
The code you show is effectively emulating a small subset of the features of vector. Namely, an array-like container that is aware of its size.
Ok, this code might work, note that you are no longer holding a pointer to a pointer, but a simple array - which may or may not work for what you are trying to do:
typedef struct tagnode
{
...
} node;
typedef struct tagproblem
{
int length;
node *x;
tagproblem(int len) : length(len)
{
x = new node[length];
}
~tagproblem()
{
delete [] x;
}
} problem;
//Now create...
problem = new problem(2);

char array interpreted as a char pointer in a constructor help please

#ifndef ASSETS_H_INCLUDED
#define ASSETS_H_INCLUDED
#include <vector>
#include string.h>
const int ID_Max = 100;
typedef char ID[ID_Max];
struct node;
struct people{
std::vector<ID> T_ID;
std::vector<node*> Nodes;
people(ID t, node* person){
T_ID.push_back(t);
Nodes.push_back(person);
}
people(){}
};
struct node {
ID T_ID;
node* Parent;
people* leftChildren;
node* rightChild;
node(ID t, node* p, node* l, node* r) :I_ID(t), Parent(p), rightChild(r)
{leftChildren = new people(); }
};
#endif // ASSETS_H_INCLUDED
My problem is this it is interpreting ID as a char pointer when in the constructor so this is the constructor people::people(char*, node*) when I want people::people(char[ID_Max], node*) same for node. If you have advise it would be very appreciated.
If you write a function signature with an array type in it, it's the same as using a pointer, e.g. this:
void f(char p[]);
is the same as this:
void f(char *p);
That looks like it's the root of your problem here. You might be better off with e.g. a std::array<char,ID_Max> (in C++11), or a std::vector<char> (in C++98). You can then get a pointer to the start of the contiguous memory it contains using &cont[0]. As a minor nit, I seem to recall that the memory for vector wasn't strictly guaranteed to be contiguous in C++98, but it always was contiguous in practice (you could rely on it). The wording was fixed in C++03.

Pointer to a C++ structure

If I create a structure in C++ like this:
typedef struct node {
int item;
int occurrency;
};
I know that a structure is allocated in memory using successive spaces, but what is the name of the structure (node in this example)? A simple way to give a name to the structure?
In C++ you don't have to use typedef to name a structure type:
struct node {
int item;
int occurrency;
};
is enough.
A pointer to an instance of that struct would be defined as node* mypointer;
E.g: You want to allocate a new instance with new:
node* mypointer = new node;
In C
struct node {
int item;
int occurrency;
};
is a tag, and by itself, it doesn't represent a type.
That is why you cannot do
node n;
You have to do
struct node n;
So, to give it a "type name", many C programmers use a typedef
typedef struct node {
int item;
int occurrency;
} node;
That way you can do
node n;
Instead of
struct node n;
Also, you can omit the tag and do the following
typedef struct {
int item;
int occurrency;
} node;
However, in C++ this all changes, the typedef syntax is no longer needed. In C++ classes and structs are considered to be user-defined types by default, so you can just use the following
struct node {
int item;
int occurrency;
};
And declare nodes like this
node n;
node is the name of the type. You can have multiple objects of that type:
struct node {
int item;
int occurrency;
};
node a;
node b;
In this example, both a and b have the same type (==node), which means that they have the same layout in memory. There's both an a.item and a b.item.