How to create an array of pointers to structure using new? - c++

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.

Related

C++ Creating Array of Pointers to Nodes in Directed Graph

I'm trying to create a directed graph represented by an array of pointers to nodes, but I'm struggling to add nodes into each index of the graph. Here is what I have:
struct Node {
int index;
list<Node*> outgoingNodes;
};
struct Graph {
Node* nodePointers; // Array of pointers to nodes in graph
int N; // Number of nodes in graph
};
Here is how I am creating the graph:
Graph* graph = new Graph();
graph->N = 7;
graph->nodePointers = new Node[graph->N];
I then try to add a node into index 0 in the graph in the following way, but I get an error that "operand types are 'Node' and 'Node*'":
Node* a = new Node();
a->index = 0;
graph->nodePointers[0] = a;
Without changing either of my structs, how could I correctly add a node into an index in my graph's array of node pointers?
Thanks for any help!
Node* nodePointers is a pointer to an array of Nodes. If you want an array of Node pointers, you need to declare it as Node** nodePointers, and allocate the array with new Node*[graph->N]:
struct Graph {
Node** nodePointers; // Array of pointers to nodes in graph
int N; // Number of nodes in graph
};
int main() {
Graph* graph = new Graph();
graph->N = 7;
graph->nodePointers = new Node*[graph->N];
...
}
First:
struct Node {
int index;
list<Node*> outgoingNodes;
};
Although correct, it is inefficient for no apparent reason. Almost always prefer a vector over a list. It is as easy to work with, but takes less memory and works faster on almost any conceivable use case:
struct Node {
int index;
std::vector<Node*> outgoingNodes;
};
Next, the code:
struct Graph {
Node* nodePointers; // Array of pointers to nodes in graph
int N; // Number of nodes in graph
};
Holds a block of Node objects, not pointers to nodes. The best thing is to use a vector of pointers:
struct Graph {
std::vector<std::unique_ptr<Node>> nodePointers; // pointers to nodes in graph
};
This way deallocation and memory management will be automatic.
Then your usage example becomes:
// are you sure graph has to be on the heap?
auto graph = std:: make_unique<Graph>();
graph->nodePointers.resize(7);
I then you can add a node into index 0 in the graph in the following way:
graph->nodePointers[0] = std::make_unique<Node>();
graph->nodePointers[0]->index = 0;
This was the better way to do it, but if you insist on:
Without changing either of my structs, how could I correctly add a
node into an index in my graph's array of node pointers?
Then you should note that "graph's array" is not made of pointers, but of nodes. So adding nodes is done differently:
// you can still allocate the graph on the heap, but the following way is safer
Graph graph;
graph.N = 7;
graph.nodePointers = new Node[graph.N];
But now nodePointers is a misnomer, because it should be named nodes (not pointers).
Then add a node into index 0 in the graph in the following way (by this point it is already constructed):
graph->nodePointers[0].index = 0;
And adding an edge looks lije:
graph->nodePointers[0].outgoingNodes.push_back(&graph->nodePointets[2]);
At line graph->nodePointers[0] = a; change this to graph->nodePointers[0] = *a; It will work.
Now let me explain you, Suppose you want an array of int then you can declare it as int x[10] or int *x=new int(10). What it shows in second case that x is an pointer which points to int object not to int pointer. I hope you got your solution.

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!

Linked Lists with vectors

I am trying to perform certain operations through linked lists on vectors.
We have been given a struct type vector
typedef struct{
int *array; // a pointer to vector's storage
int size; // the current number of elements in the vector
int cap; // the current capacity of the vector;
int init_cap; // the initial capacity the vector was initialised with.
} vector;
Now, I want to make a function that takes in a pointer to the vector struct, and initialises it with the given capacity. All the fields are to be initialised. I want to do this using linked list.
Here is my code
#include <iostream>
using namespace std;
typedef struct node {
int *array; // a pointer to the vector's storage
int size; // the current number of elements in the vector
int cap; // the current capacity of the vector
int init_cap; // the initial capacity the vector was initialised with
node *next;
} vector;
node *head = NULL;
Can I make nodes from a vector struct, like I have attempted in the code written above?
void vector_init(vector *v, int capacity){
//initialising the vector with the given capacity
v->size = capacity;
v->cap = capacity;
v->init_cap = capacity;
//linked list with nodes created and values initialised
node *temp, temp2;
temp = head;
temp = new node;
temp->size = capacity;
temp->cap = capacity;
temp->init_cap = capacity;
temp->next = temp2
temp2 = new node;
temp2->size = capacity;
temp2->cap = capacity;
temp2->init_cap = capacity;
temp2->next = NULL;
}
Have I made the linked list, and initialised the values correctly? If we do not create temporary points temp and temp2, and just use v->size etc to initialise the fields, would that make it a linked list?
You have many problems with your code.
Don't use the name vector - there is a structure called std::vector and it is easy to get confused.
If you want to initialize the values of the structure, don't create an external, separate function for that - it's not c++'ish. Create a struct constructor initializing all the values instead.
You don't initialize the array variable anywhere in your code. You should allocate space for it depending on the capacity given in the constructor.
Don't use the name 'array' for the variable. There is a structure called std::array in C++, and it might be confusing.
Your implementaion makes very little sense to me. You have a linked list of arrays right now; if you would like to functionally replace an array of ints with a linked list of ints, each node should contain one int value.
If, for some reason, you would want to stick to this implementation, you also need some kind of update function that would automatically update size and cap variables while adding or removing elements from array. Otherwise you are sure to end up forgetting about it and you're gonna have mess in your structure. Make this function a part of the structure - it shouldn't be an external function.
That typedef struct node doesn't make sense even after changing the word vector to something else - you don't use it anyway in your code.
You are using the same name for two different structures; vector is at first defined as having 4 fields, and in the next lines as having 5 fields.
Technically yes, this is a linked list, but your vector_init() function does not work as it should. Apart from what I've written above:
You should avoid making functions depend on the global variable, in this case head. It could be passed as a parameter.
These two lines:
temp = head;
temp = new node;
don't make sense. The first one makes the variable temp point to head; the second one tells temp to start pointing to the new variable as you're using operator new, which allocates space and return a pointer to the newly created variable. As a result, you don't operate on the variable head, when you do further operations, but on another variable that will be lost after the temp pointer gets invalidated.
You don't need temp and temp2 variables at all. They only bloat the code.
These two lines:
temp->next = temp2;
temp2 = new node;
should switch places since now you assign a pointer that hasn't been yet initialised.
After writing all this stuff I've realised that the function is incorrect in general. For some reason, you first work on the parameter v, and then do something unrelated to it.
Also, your instructor is just not right saying that you can solve all types of problems with the use of linked lists. It may solve some problems in certain situations, or create new problems, depending on the context.
I don't want to be rude, but there seems to be something fundamentally wrong with the concept of the task you have been given itself. I guess someone really hasn't thought it through.

Linked list, Struct, Dynamic memory allocation

Struct node
{ char name [30];
int length;
node * next;
};
Using dynamic memory allocation how will i use the struct above to create a list to hold any number of nodes? without knowing that number beforehand.
Please read through this simple and quick tutorial on Singly linked lists in C++

linked list first member variable of node structure always next node

Suppose you have a linked list of nodes as defined below:
C++ code
struct node {
node *next;
int i ;
};
Is there any benefit in making the next pointer as the first member variable of the structure ?
I think that people try this via the above approach (I may be wrong here)
node n, m;
*n=&m;
If above is right, is it right to code like above. What's the right way?
Is there any benefit in making the next pointer as the first member
variable of the structure ?
A very small performance benefit can be reached to reduce the assembly instruction size in loads from and writes to zero offset members, but only in classes without virtual table (vtbl is a omitted first member).
If you want prebuild a scope/global allocated list, its elements can be initialized as mentioned.
You can try it:
struct node {
struct node* next;
int i;
};
node z = {0}, c={&z}, b={&c}, a={&b};
node * stack = &a;
you can find very useful information about liked list searching for 'linux kernel linked list':
Linux Kernel Linked List Explained
How does the kernel implements Linked Lists?
I working now in my own design of 'intrusive node' general purpose containers using c++ templates, perhaps this question might seem interesting.
node n, m;
*n = &m;
is not legal code, perhaps you mean
node n, m;
n.next = &m;
but normally this would be done with dynamic allocation
node* n = new node;
n->next = new node;
because normally you would use node to create a variable length list. Since the length of the list varies there is no way to declare the right number of variables, instead you must allocate the nodes dynamcally.