how to create a array of pointers - c++

I'm trying to create an array of pointers for my hashtable. But I'm having trouble because I keep on getting segmentation faults for my functions(i.e. add, remove, find, delete functions) and I'm not sure if it's because I don't have my array of pointers declared and defined correctly. Here is what I have:
Node **array = new Node* is this how you would create a dynamic array of pointers?

I think you can use :
Node **array = new Node*[10];
setting the pointer :
Node node;
array[0] = &node;
and remember to delete :
delete[] array;

Related

Uninitialized memory warning on structs instantiated with new [duplicate]

This question already has answers here:
How do I declare a 2d array in C++ using new?
(29 answers)
Closed 1 year ago.
So I have a Node struct
struct Node
{
int x = 0;
};
I make 20 Node*s. My understanding is that Node** is a pointer to the start of an array that holds pointers to Nodes.
constexpr int mazeSize = 20;
Node** testMaze = new Node * [mazeSize];
After this, I started getting warnings and errors when I tried to do anything with it. Examples:
testMaze[0]->position.x == 0; //->Using uninitialized memory `*testMaze` and
What I understood from this error: *testMaze is dereferencing the array of pointers, which means it's referring to the first Node object in that array. If this is the case than how would I initialize it? If I simply created the Node* as so:
Node* node = new Node;
node->x = 0;
Than it works fine and there is no need to initialize it, so why not with the way I am doing it? I also don't understand how to initialize a struct.
Another examlpe:
testMaze[0]->x == testMaze[1]->x //->Runtime error: Access violation reading error
testMaze[0]->x = 0; //->Runtime error: Access violation writing error
How can I fix these problems? Thanks.
Problems:
constexpr int mazeSize = 20;
Node** testMaze = new Node *[mazeSize]; //this makes 20 pointers, but the pointers dont point to anything
testMaze[0]->position.x == 0; //undefined, as testMaze's pointers do not point to anything
This works because you make a new node, not a new pointer to a pointer to a node.
Node * node = new Node;
node->x = 0;
As for this:
testMaze[0]->x == testMaze[1]->x; //This is an undefined pointer, it doesn't point to anything, and you are trying to access it, so UNDEFINED behavior
testMaze[0]->x = 0; //This is a undefined pointer, it doesn't point to anything, and you are trying to access it, so UNDEFINED behavior
}
I would just do this:
Node** Make(int size) {
Node** temp = new Node * [size];
Node* pool = new Node[size];
for (int i = 0; i < size; ++i) {
temp[i] = &pool[i];
}
}
This makes your array of pointers, makes your pointers point to actual pointers which point to actual values.
Also, don't forget to delete[] your Node**s and Node*s, or you'll have a memory leak!
Always remember that pointer types are separate, concrete types with their own type and size. A pointer to T T* basically boils down to a small chunk of memory that is used to store an address to another memory area, which (hopefully) contains an instance of some type T.
With
Node** testMaze = new Node * [mazeSize];
you are allocating an array of maxSize pointer sized elements of type Node* and sizeof(Node*) (which on modern platforms is usually 4 or 8 bytes, depending if your executable is meant to run in 32 bit or 64 bit mode).
These newly created pointers are not initialized, and thus point to invalid addresses, unless you also zero initialize the array:
Node** testMaze = new Node * [mazeSize] {};
assert (testMaze[0] == nullptr); // holds true
In order to get an maxSize instances of Node, you have to, well, create maxSize instances of Node:
Node** testMaze = new Node* [mazeSize];
for (std::ptrdiff_t i {}; i < maxSize; ++i) {
testMaze[i] = new Node { /* insert parameters here */ };
}
Given that you are using constexpr, I infer the revision of C++ you are targeting is C++11 or newer. In this case, you should be aware that operator new and operator new[] are almost always the wrong choice when writing modern C++, given that they only returns pointers whose ownership and lifetime you then have to manage by hand.
You most definitely should start using STL containers, such as std::vector and std::array, which are easier to use and can avoid you a great deal of unnecessary pain. If you insist on using new, at least give a look to std::unique_ptr, which wraps a pointer or C array and automatically calls delete or delete[] as soon as it goes out of scope.

How to store a node in an array C++?

Isn't this a way to store a node in an array? When I try to run it I get a segmentation fault. I know that happens if you try to access memory that you do not have permission for.
In this code am I not assigning a node in an array and printing its data?
struct Node{
int data;
struct Node* next;
};
struct Node* head = NULL;
int main(){
struct Node* arr[10];
head->data = 2;
head->next = NULL;
arr[1] = head;
std::cout << arr[1]->data;
}
You are not dealing with Nodes's here, but Node pointers. They are not pointing to valid memory, unless you allocate it.
Also, don't use NULL, use nullptr instead.
head = nullptr;
head->data = 42; // this is UB, could be a segfault
If you want to do that, you have to allocate it
head = new Node{};
head->data = 42; //ok
The same logic applies for arr
arr[1] = new Node{}; // now arr[1] is pointing to valid memory
I'm not sure why you want an array of Node pointers, though. Your Node struct looks like a conventional linked-list Node, and there's a linked-list tag, so I'm guessing you want to implement linked-lists.
In that case, you don't need an array of Node pointers at all. The entire linked-list should be connected through the head.
If you just want an array of Nodes, then you can do that, and not worry about memory allocation at all.
Node arr[10] {};
arr[1].data = 42; // ok

How to create an array of pointers to structure using new?

I am trying to create a graph using linked list styled nodes where each node is a structure containing a key and an address to the next node, but I want to join multiple nodes to one node so I tried creating an array of pointers to structure and initialize them using new dynamically but it throws an error saying that it "cannot convert node*** to node** in assignment".
I have tried using struct node* next[] but it didn't work well. What am I missing here? Should I just use a vector of pointers instead of an array?
struct node
{
int key;
struct node** next;
};
int main()
{
struct node A;
A.key = 12;
A.next = new node**[2];
return 0;
}
Should I just use a vector of pointers instead of an array?
This is often an ideal solution. This would fix the memory leak that your program has (or would have if it compiled in the first place). An example:
struct node
{
int key;
std::vector<node*> next;
};
// usage
A.next.resize(2);
Vector does have space overhead, which can be a problem with big graphs because the total overhead increases linearly in relation to number of nodes. If vector is not appropriate for you, an alternative is std::unique_ptr, which does not have any overhead compared to a bare pointer:
struct node
{
int key;
std::unique_ptr<node[]> next;
};
// usage
A.next.reset(new node*[2]);
new node**[2];
What am I missing here?
You're attempting to create an array of node** when you need an array of node*.
Should I just use a vector of pointers instead of an array?
YES!
After including the vector library, then in your structure, you would have a member like this:
std::vector<node*> next;
This is the C++ approach, using raw pointers is the C approach.
As an encyclopedian information though, with raw pointers, you would do:
A.next = new node*[2];
which means an array of two pointers.

C++ trying to delete Binary Tree and move it to Vector

So I'm trying to write a function that places all of the values of a binary tree into a vector, which will later be used to recreate it. But when I try to call this function, I get an error:
Error in `./bst': double free or corruption (fasttop):
This is the function I'm using. The vector itself is a private variable containing nodes. size() returns the size of the tree and is working.
void BST::swapvector()
{
Node *ptr = m_root;
while (size() != 0)
{
if (ptr->m_left != NULL) {
ptr = ptr->m_left;
} else if (ptr->m_right != NULL) {
ptr = ptr->m_right;
} else {
Node *temp = ptr;
myvector.push_back(ptr); //starting from root, we traverse until we reach the bottom and then add ptr to the vector
ptr = m_root;
delete temp; //once we're finished, we delete temp
}
}
}
Does anyone know why this isn't working? Thanks!
It's obvious why this isn't working.
} else {
Node *temp = ptr;
myvector.push_back(ptr); //starting from root, we traverse until we reach the bottom and then add ptr to the vector
ptr = m_root;
delete temp; //once we're finished, we delete temp
}
You're storing a pointer to Node into vector and then deleting that Node with delete temp. After that pointer stored into vector points to garbage or non-existent memory.
"...a function that places all of the values of a binary tree into a vector..."
No, you're not storing binary tree values, you're storing pointers to binary tree values (Node objects).
There are two things you can do:
If the binary tree will not be freed nor changed for the lifetime of myvector then you can just remove the delete temp; line.
If assumption in the first case is not true, then you need to store Node elements into vector, not pointers to them. So, define myvector as vector<Node> myvector; instead of vector<Node *> myvector; and change myvector.push_back(ptr); to myvector.push_back(*ptr);.
You cannot delete temp after you place it a vector. Also, how is your vector defined? There might be problem there.
Also you should use iterators instead of push_back() function. It doesn't work well with pointers.
And, why does everyone insist on using c-style pointers. Use shared or unique pointers. Please?
Type of error usually signifies that a pointer being freed twice.

Create Dynamically Allocated Array with Pointers to Structs C++

So I currently have a simple struct (linkedlist) that I will be using in a HashMap:
struct Node {
std::string key, value;
Node* head;
}
I'm currently trying to dynamically allocate an array with pointers to each struct. This is what I have right now ...
Node* nodes = new Node[100]
I understand this allocates an array of 100 nodes into memory (which I will have to delete later on); however, upon iteration to try to transverse these nodes (which I an implementing as a linked list)...
for (int x = 0; x < 100; x++) {
Node current = nodes[x]; // Problem is I wanted an array to node pointers. This is not a pointer.
while (current != nullptr) { // this isn't even legal since current is not a pointer.
// DO STUFF HERE
current = current.next; // This is not a pointer access to a method. I'm looking to access next with current->next;
}
}
Hopefully I was clear enough. Can someone how to allocate a dynamic array of pointers to structs? So far I'm able to dynamically allocate an array of structs, just not an array of pointers to structs.
There are two approaches. Either you allocate an array of structures and introduce one more pointer that will point to the element in the array that will play the role of the head.
For example
Node *head = nodes;
(in this case head points to nodes[0])
After the list will not be needed you have to delete it using operator
delete [] nodes;
Or you can indeed to allocate an array of pointers to the structure like this
Node **nodes = new Node *[100];
But in this case each element of the array in turn should be a pointer to a dynamically allocated object;
And to delete the list you at first have to delete each object pointed to by elements of the array for example in a loop
for ( int i = 0; i < 100; i++ ) delete nodes[i];
and then to delete the array itself
delete [] nodes;
It is a good idea to initialize each element of the array with zeroes when the array is allocated for example
Node **nodes = new Node *[100]();
I suggested you this structure:
class myList {
struct Node {
string value;
Node* next;
}
/*Public methods .. Add/Set/Get/Next/isEmpty.. etc ... */
Node* head, *tail;
};
in main:
myList* lis = new myList[number];
then you have number of lists! and do all work in class by method's and operators, like if you want the next node just call lis[0].getNext();
if you want to skip current node dolis[0].Next(); ... etc ..
this how to work, what you try to do is looks like C program!