When declaring a pointer variable, is there ever a use for more than one asterisk? I know when you want to have a pointer point to another you would use multiple, but just to clarify, when declaring you still only put one?
Weard things: an example of 3 asterisks:
const char **stringArray;
now, if you want to allocate this array in a function as an argument, you need the following:
void stringAllocator(const char ***stringArray, int size) {
*stringArray = (const char **) malloc(size);
}
...
stringAllocator (&stringArry, 20);
...
So, you can imagine more than 3 as well, though i had never saw more than 4 :-)
an a bit weirder stuff in c++ using stars in combination with &
void stringAllocator(const char **&stringArray, int size) {
stringArray = (const char **) malloc(size);
}
...
stringAllocator (stringArry, 20);
...
In the above case works as a star reduction technique. It does the same as the first examle
When declaring a pointer variable, is there ever a use for more than one asterisk?
Sure, there are uses for declarations of pointer to pointer variables.
Let's suppose you have a function that does allocate some class instance internally, but needs to indicate failure at the same time. You can give it a signature like
bool CreateSomeType(SomeType** pointerToSomeTypePointer) {
try {
*pointerToSomeTypePointer = new SomeType();
}
catch(...) {
return false;
}
return true;
}
and being called like this
SomeType* ptr = nullptr;
if(CreateSomeType(&ptr)) {
// Use ptr
// ...
delete ptr;
}
else {
// Log failure
}
A common use case of two stars is when a function has to alter a pointer value, e.g. in ADT implementations like "Stack".
Though this design is more C than C++ (in C++ you can use other mechanisms like references), see the following example. I wrote it in "C"-style (even if you mentioned C++):
struct node {
int x;
struct node* next;
};
// this one works:
void insertBeforeHead(node** head, int value) {
struct node* newNode = (struct node*)malloc(sizeof(struct node));
newNode->next = *head;
newNode->x = value;
*head = newNode; // alters the pointer value of the caller
}
// this one does not work:
void insertBeforeHead2(node* head, int value) {
struct node* newNode = (struct node*)malloc(new Node);
newNode->next = head;
newNode->x = value;
head = newNode; // alters only the local copy of the pointer value
}
int main () {
struct node* mainHead = NULL;
insertBeforeHead(&mainHead,10); // changes the value of mainHead
insertBeforeHead2(mainHead,20); // does not change the value of mainHead, althouth it should.
}
Related
I have a struct like this:
struct ClientNode
{
string name;
int flightnumber;
int clientno;
ClientNode * right;
ClientNode* left;
};
then I have declared a pointer of this struct:
ClientNode* root = new ClientNode;
in a function I have initialized clientno for root like this:
root->clientno = 11;
and then I want to send root as an argument to a function:
ClientNode newnode;
root = Insert_to_AVL_Tree(&newnode, root);
and here is my Insert_to_AVL_Tree:
ClientNode* clientclass::Insert_to_AVL_Tree(ClientNode* Node, ClientNode* root)
Here is where the error happens, I have initialized root->clientno but it seems that it changes when I pass it to another function thus it can't compare to values in the if, also node->clientno has the correct value that has been read from a file in another part of my code:
if (Node->clientno < root->clientno)
root->left = Insert_to_AVL_Tree(Node, root->left);
what is the correct way to get the root->clientno value in another function?
here is the value shown for root->clientno
here is the value for node->cleintno
For passing Pointer to functions the best way I use is double pointer
void clear(int **p)
{
*p = 0;
}
int main()
{
int* p;
clear(&p);
return 0;
}
struct Node{
int value;
Node *next;
Node(int val) :value(val), next(nullptr){}
};
class Stack
{
public:
void push(int val);
int pop();
bool is_empty(){ return first == nullptr; }
private:
Node *first = nullptr;
};
int Stack::pop(){
int ret = first->value;
first = first->next;
return ret;
}
void Stack::push(int i){
if (is_empty()){
first = &Node(i);
return;
}
Node oldFirst = *first;
first = &Node(i);
first->next = &oldFirst;
}
Here is how I wrote the code, however, there is a problem that when I finished push() the pointer of first isn't point to the right object. I'm wondering how I can solve that problem.
The expression &Node(i) creates a temporary object and give you a pointer to it. And then the temporary object is immediately destructed, leaving you with a pointer to a non-existing object.
You need to use new to allocate a new object.
You have a similar problem with &oldFirst, which give you a pointer to a local variable, which will be destructed once the function returns. You need to use a pointer variable.
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();
}
};
This is not a real question, since I've already solved the problem myself, but I still need some clarifications about the mechanism behind assigning an array's address to a pointer of the same type when the array is a class member of a nested class.
The following code is fully functioning, although it may lack some error_check. It is only meant to show how I made my (real) program work.
HEADER (linkedList)
class linkedList
{
public:
linkedList();
~linkedList();
int* getArray();
void forward();
private:
class listNode
{
public:
listNode();
~listNode();
friend class linkedList;
private:
int array[3];
listNode* next;
};
listNode *first;
listNode *current;
};
CPP (linkedList)
linkedList::linkedList()
{
first = new listNode;
current = first;
}
//~~~~~~~~~~~~
linkedList::~linkedList()
{
delete first;
first = 0;
current = 0;
}
//~~~~~~~~~~~~
int* linkedList::getArray()
{
if (current)
{
return &(current->array[0]);
}
}
//~~~~~~~~~~~~
void linkedList::forward()
{
if (current->next)
{
current = current->next;
}
}
//-------------------------
//-------------------------
//-------------------------
linkedList::listNode::listNode()
{
next = 0;
for (int i = 0; i < 3; i++){array[i]=((i+1)*3);}
}
//~~~~~~~~~~~~
linkedList::listNode::~listNode()
{
}
CPP (main)
#include <iostream>
#include "linked_list.h"
using namespace std;
int main()
{
linkedList list;
int *myArray;
myArray = list.getArray();
for (int i = 0; i < 3; i++){cout << myArray[i] << " ";}/**/cout << "\n\n";
return 0;
}
The real program is meant to move through a linked list made of nodes which contain 3 integer values in an array of int type, retrieve the three values and use them as parameters for some other functions.
Now, to do so I have to return the address to the first element of the array contained in the node through an accessor.
Apparently, the only way to do it is by returning the reference to the first element of the array in the node to which the linkedList's member variable current points to:
return &(current->array[0]);.
Why?
I've got to this solution through trial and error with very little knowlegde of the reasons that brought me to build this expression as it is.
Usually, when you want to assign the address of an array to a pointer, you just do so:
int main()
{
int array[3];
int* pArray;
pArray = array;
}
And that's it, because the name of the array itself is enough to retrieve the address of its first element.
The exact same result can be achieved by doing this (tested):
int main()
{
int array[3];
int* pArray;
pArray = &(array[0]);
}
Both methods are also valid when the accessor returns the address from a member variable of its own class.
But why, when accessing the member variable of a nested class, I'm forced to use the second method?
What are the logic stages that make it the only viable method?
But why, when accessing the member variable of a nested class, I'm forced to use the second method?
You aren't:
return current->array;
and
return &(current->array[0]);
Both do the same thing when the return type is int*. You aren't forced to use the second way.
Also, there's a bug in getArray. You don't return anything if current is null.
To be pedantic...
Apparently, the only way to do it is by returning the reference to the first element of the array in the node to which the linkedList's member variable current points to:
return &(current->array[0]);.
You're returning the address i.e. a pointer. Reference means something else.
I am trying to remove the left child (10) of a sample binary search tree using two methods:
Method1: By passing pointer to a pointer to the current node.
Method2: By passing address of the pointer to the current node. This does not removes the node, but calling delete corrupts the pointer arrangement, causing a crash while printing the nodes.
The tree looks like this and I am trying to delete 10 and replace it with 5
20
|
10--|---30
|
5---|
I have some understanding of pointers. But still, I am not clear with this behavior of pointers.
#include <iostream>
class Node
{
public:
Node(int key) : leftChild(0), rightChild(0), m_key (key){}
~Node(){}
Node *leftChild;
Node *rightChild;
int m_key;
};
Node* build1234(int, int, int, int);
void print(Node *);
void print1234(Node *);
void removeLeft(Node **nodePtr)
{
Node *oldPtr = *nodePtr;
if(*nodePtr)
{
*nodePtr = (*nodePtr)->leftChild;
delete oldPtr;
}
}
int main()
{
Node *demo1 = build1234(10, 20, 30, 5);
Node *demo2 = build1234(10, 20, 30, 5);
print1234(demo1);
print1234(demo2);
//Method1 - 10 is correctly removed with 5
Node **nodePtr = &demo1;
nodePtr = &(*nodePtr)->leftChild;
removeLeft(nodePtr);
print1234(demo1);
//Method2 - 10 is not removed
Node *node = demo2;
node = node->leftChild;
removeLeft(&node);
print1234(demo2);
return 0;
}
Node* build1234(int B, int A, int C, int D)
{
Node *root = new Node(A);
root->leftChild = new Node(B);
root->rightChild = new Node(C);
root->leftChild->leftChild = new Node(D);
return root;
}
void print(Node *node)
{
if(node)
{
print(node->leftChild);
std::cout << "[" << node->m_key << "]";
print(node->rightChild);
}
}
void print1234(Node *node)
{
std::cout << std::endl;
print(node);
}
Note: This question is not about BST, but pointers. If you see the two calls to removeLeft(nodePtr) and the removeLeft(&node) in the main() function.
How are these two different?
Why the second method fails to achieve the desired result?
In the first case, you are passing an address of a pointer that exists in the tree, so you are modifying the contents of the tree directly.
In the second case, you are passing an address of a variable that is local to main() instead. The tree is not modified, and deleting from the address is accessing stack memory, which is why it crashes
You're overthinking it. All you need is a function removeLeft(Node*) that unhooks the left node and deletes it, recursively:
void removeLeft(Node * p)
{
removeBoth(p->leftChild); // recurse, OK if null
delete p->leftChild; // OK if already null
p->leftChild = 0; // necessary to make recursion terminate
}
void removeBoth(Node * p)
{
if (!p) return;
removeLeft(p);
removeRight(p);
}
If you are bad with pointers consider using smart pointers.
When using smart pointers use shared_ptr<Node> instead of Node * and make_shared(new Node); instead of new Node and remove all deletes. now you can handle pointers without caring for deletes and memory corruption.