Dynamic memory allocation inside static function - c++

I want to understand what happens, if we allocate dynamic memory inside a static function? Each call to static function returns the same memory, or every time a new memory is created??
For example-
class sample
{
private:
static int *p;
public:
static int* allocate_memory()
{
p = new int();
return p;
}
};
int* sample::p=NULL;
int main()
{
int *p= sample::allocate_memory();
int *q = sample::allocate_memory();
cout << p << " " << q << endl;
if (p== q)
cout << "we are equal";
}
In this program both memory locations inside main() are different. if we move static int *p; inside allocate_memory() function, like static int *p = new int; both memory location will come same.
I want to understand what is the difference. static is always static, weather it is inside class or inside function, then why behavior is different??
Devesh

One of the issues here is that the keyword static means a lot of different things in C++ depending on context. You have stumbled upon two of these.
If a member variable is declared static, that means the class itself has one copy of this variable which is shared between all instances.
If a local variable in a function is static, it means the value of that variable persists in-between function calls. It always refers to the same location in memory, even between calls (or in recursive calls). For such a variable, the initializer is only only executed the first time the function is entered.
So, if you've tried this:
static int* allocate_memory()
{
static int p = new int();
return p;
}
the assignment to a new int() will only be called the first time you call the function. This is because, when written as part of the variable declaration, it is an initializer. If, however, you would do this:
static int* allocate_memory()
{
static int p;
p = new int();
return p;
}
Then, you would see the same behaviour as in your other case.

Every time you call allocate_memory, a new int is created. p is static, but what it points at will change.
To return a pointer to the same object every time:
static int* allocate_memory()
{
if(!p)
{
p = new int();
}
return p;
}
In your main method, p and q will be different regardless of how allocate_memory works, as they are two different pointers. If you de-reference p and q, you will compare what they are pointing to:
if(*p == *q)
{
cout << "Equal";
}

Related

How do I correctly insert and erase from malloc-allocated dynamic array? [duplicate]

Under which circumstances would you want to use code of this nature in c++?
void foo(type *&in) {...}
void fii() {
type *choochoo;
...
foo(choochoo);
}
You would want to pass a pointer by reference if you have a need to modify the pointer rather than the object that the pointer is pointing to.
This is similar to why double pointers are used; using a reference to a pointer is slightly safer than using pointers.
50% of C++ programmers like to set their pointers to null after a delete:
template<typename T>
void moronic_delete(T*& p)
{
delete p;
p = nullptr;
}
Without the reference, you would only be changing a local copy of the pointer, not affecting the caller.
David's answer is correct, but if it's still a little abstract, here are two examples:
You might want to zero all freed pointers to catch memory problems earlier. C-style you'd do:
void freeAndZero(void** ptr)
{
free(*ptr);
*ptr = 0;
}
void* ptr = malloc(...);
...
freeAndZero(&ptr);
In C++ to do the same, you might do:
template<class T> void freeAndZero(T* &ptr)
{
delete ptr;
ptr = 0;
}
int* ptr = new int;
...
freeAndZero(ptr);
When dealing with linked-lists - often simply represented as pointers to a next node:
struct Node
{
value_t value;
Node* next;
};
In this case, when you insert to the empty list you necessarily must change the incoming pointer because the result is not the NULL pointer anymore. This is a case where you modify an external pointer from a function, so it would have a reference to pointer in its signature:
void insert(Node* &list)
{
...
if(!list) list = new Node(...);
...
}
There's an example in this question.
I have had to use code like this to provide functions to allocate memory to a pointer passed in and return its size because my company "object" to me using the STL
int iSizeOfArray(int* &piArray) {
piArray = new int[iNumberOfElements];
...
return iNumberOfElements;
}
It is not nice, but the pointer must be passed by reference (or use double pointer). If not, memory is allocated to a local copy of the pointer if it is passed by value which results in a memory leak.
One example is when you write a parser function and pass it a source pointer to read from, if the function is supposed to push that pointer forward behind the last character which has been correctly recognized by the parser. Using a reference to a pointer makes it clear then that the function will move the original pointer to update its position.
In general, you use references to pointers if you want to pass a pointer to a function and let it move that original pointer to some other position instead of just moving a copy of it without affecting the original.
Another situation when you may need this is if you have stl collection of pointers and want to change
them using stl algorithm. Example of for_each in c++98.
struct Storage {
typedef std::list<Object*> ObjectList;
ObjectList objects;
void change() {
typedef void (*ChangeFunctionType)(Object*&);
std::for_each<ObjectList::iterator, ChangeFunctionType>
(objects.begin(), objects.end(), &Storage::changeObject);
}
static void changeObject(Object*& item) {
delete item;
item = 0;
if (someCondition) item = new Object();
}
};
Otherwise, if you use changeObject(Object* item) signature you have copy of pointer, not original one.
Refer the code below:
When we pass x as Node *x, a new variable is created with the same address passed on by the caller function.
If you modify the value pointed by the pointer, that change will be reflected in the caller function variable.
But if we change the value of the pointer itself it will not be reflected in the caller function because callee function has the copy of the passed pointer not the original pointer itself.
void increment(int *x) {
(*x)++;
x++;
cout << x << endl; // prints 0x7ffe9f8e1900
}
int main() {
int a = 10;
int *x = &a;
increment(x);
cout << *x << endl; // prints 11
cout << x << endl; // prints 0x7ffe9f8e18fc
return 0;
}
Now, check the below code:
When we pass x as Node *&x, we pass a reference of the original variable present in the caller function meaning these two variable (caller and callee root) are same, their name may differ.
if we modify the value pointer by the pointer, that change will be reflected in the caller function variable.
Now if we change the value of the pointer itself it will also be reflected in the caller function variable.
void increment(int* &x)
{
(*x) ++;
cout << *x << endl; // prints 11
x++;
cout << x << endl; // prints 0x7fffb93eba70
}
int main()
{
int a = 10;
int *x = &a;
increment(x);
cout << *x << endl; // prints garbage
cout << x << endl; // prints 0x7fffb93eba70
return 0;
}

Simple code regarding code to read from a struct pointer

I'm trying to understand pointers so I did this code:
#include<iostream>
using namespace std;
struct teste{
int a;
bool b;
};
void say (struct teste* a) {
cout << (*a).a << (*a).b << "\n";
}
int main() {
teste* e;
(*e).a=2;
(*e).b=0;
say(e);
}
which gives me Segmentation Fault
but the following:
#include<iostream>
using namespace std;
struct teste{
int a;
bool b;
};
void say (struct teste* a) {
cout << (*a).a << (*a).b << "\n";
}
int main() {
teste e;
e.a=2;
e.b=0;
say(&e);
}
I know that the second one is prefered but why the first one will not work? I think I did everything all right.
teste* e;
(*e).a=2;
(*e).b=0;
This gives you segmentation fault because pointer e is not initialized - it doesn't point to valid memory.
When you initialize pointer with some address say y - and then apply dereference operator, you tell it to retrieve value from the memory address y which you assigned to it. In your case, no address has been assigned to it, so you can't dereference it.
Make it point to a teste object, then you can dereference it.
Imagine you ask me "where is the airport"? I offer to write the address of it on a sticky note for you.
On the note I write:
airport
This is not very helpful, is it?
teste* e;
this says "declare a variable, e, such that it holds the address of an instance of teste in memory".
But you haven't provided an actual instance of teste for it to point to; you didn't actually assign the address of something to it.
int main() {
teste instance;
teste* e = &instance;
e->a = 2;
(*e).b = 0; // equivalent to e->a
say(e);
}
The line
teste* e = &instance;
says "declare a variable, e, such that it holds the address in memory of a teste struct, and let that address be the address-of instance (&instance)".
We could also have written
teste* e;
e = &instance;
But it's better practice to try and always initialize your variables at the time of declaration, if you can.
The -> operator is more-or-less syntactic sugar for (*e). -- it accesses through (dereferences) the pointer.
e->a
// is equivalent to
(*e).a
Where . is the member-of -> is the member-through.
Note that . and -> are distinct operators, which will become important later in your understanding of the language.
In this example, instance is a local variable and so is created on the stack. This means that when the scope ends it will be destroyed/go away.
If you need instance to stick around longer, or it is very large, you can allocate it from the "heap".
int main() {
teste* e = new teste;
e->a = 2;
e->b = 0;
say(e);
delete e;
}
Explaining new and delete is probably beyond the scope of answering this question, I leave it to you to learn about them and their use.
In the first example you declare a pointer, but that pointer points to nothing. So you get the seg. fault. You should assing a value to that pointer, being an address of an instance of teste, either declared or created in memory using new() or malloc()
You never actually allocated any memory for e. You can either declare it on the stack, then pass it as a pointer by taking it's address using operator &
int main() {
teste e;
e.a=2;
e.b=0;
say(&e);
}
or declare it on the heap using new, then delete it when you're done.
int main() {
teste* e = new teste;
e->a=2;
e->b=0;
say(e);
delete e;
}

c++, change pointer of a object inside another class [duplicate]

Under which circumstances would you want to use code of this nature in c++?
void foo(type *&in) {...}
void fii() {
type *choochoo;
...
foo(choochoo);
}
You would want to pass a pointer by reference if you have a need to modify the pointer rather than the object that the pointer is pointing to.
This is similar to why double pointers are used; using a reference to a pointer is slightly safer than using pointers.
50% of C++ programmers like to set their pointers to null after a delete:
template<typename T>
void moronic_delete(T*& p)
{
delete p;
p = nullptr;
}
Without the reference, you would only be changing a local copy of the pointer, not affecting the caller.
David's answer is correct, but if it's still a little abstract, here are two examples:
You might want to zero all freed pointers to catch memory problems earlier. C-style you'd do:
void freeAndZero(void** ptr)
{
free(*ptr);
*ptr = 0;
}
void* ptr = malloc(...);
...
freeAndZero(&ptr);
In C++ to do the same, you might do:
template<class T> void freeAndZero(T* &ptr)
{
delete ptr;
ptr = 0;
}
int* ptr = new int;
...
freeAndZero(ptr);
When dealing with linked-lists - often simply represented as pointers to a next node:
struct Node
{
value_t value;
Node* next;
};
In this case, when you insert to the empty list you necessarily must change the incoming pointer because the result is not the NULL pointer anymore. This is a case where you modify an external pointer from a function, so it would have a reference to pointer in its signature:
void insert(Node* &list)
{
...
if(!list) list = new Node(...);
...
}
There's an example in this question.
I have had to use code like this to provide functions to allocate memory to a pointer passed in and return its size because my company "object" to me using the STL
int iSizeOfArray(int* &piArray) {
piArray = new int[iNumberOfElements];
...
return iNumberOfElements;
}
It is not nice, but the pointer must be passed by reference (or use double pointer). If not, memory is allocated to a local copy of the pointer if it is passed by value which results in a memory leak.
One example is when you write a parser function and pass it a source pointer to read from, if the function is supposed to push that pointer forward behind the last character which has been correctly recognized by the parser. Using a reference to a pointer makes it clear then that the function will move the original pointer to update its position.
In general, you use references to pointers if you want to pass a pointer to a function and let it move that original pointer to some other position instead of just moving a copy of it without affecting the original.
Another situation when you may need this is if you have stl collection of pointers and want to change
them using stl algorithm. Example of for_each in c++98.
struct Storage {
typedef std::list<Object*> ObjectList;
ObjectList objects;
void change() {
typedef void (*ChangeFunctionType)(Object*&);
std::for_each<ObjectList::iterator, ChangeFunctionType>
(objects.begin(), objects.end(), &Storage::changeObject);
}
static void changeObject(Object*& item) {
delete item;
item = 0;
if (someCondition) item = new Object();
}
};
Otherwise, if you use changeObject(Object* item) signature you have copy of pointer, not original one.
Refer the code below:
When we pass x as Node *x, a new variable is created with the same address passed on by the caller function.
If you modify the value pointed by the pointer, that change will be reflected in the caller function variable.
But if we change the value of the pointer itself it will not be reflected in the caller function because callee function has the copy of the passed pointer not the original pointer itself.
void increment(int *x) {
(*x)++;
x++;
cout << x << endl; // prints 0x7ffe9f8e1900
}
int main() {
int a = 10;
int *x = &a;
increment(x);
cout << *x << endl; // prints 11
cout << x << endl; // prints 0x7ffe9f8e18fc
return 0;
}
Now, check the below code:
When we pass x as Node *&x, we pass a reference of the original variable present in the caller function meaning these two variable (caller and callee root) are same, their name may differ.
if we modify the value pointer by the pointer, that change will be reflected in the caller function variable.
Now if we change the value of the pointer itself it will also be reflected in the caller function variable.
void increment(int* &x)
{
(*x) ++;
cout << *x << endl; // prints 11
x++;
cout << x << endl; // prints 0x7fffb93eba70
}
int main()
{
int a = 10;
int *x = &a;
increment(x);
cout << *x << endl; // prints garbage
cout << x << endl; // prints 0x7fffb93eba70
return 0;
}

About reference to pointers

I've been making a tree, because planting a trees will save the planet (or just the program).
class Tree {
Node* root;
// ...
void insert(int value){
private_insert(value, root);
}
void insert_private(int value, node* n){
if(n == nullptr){
n = new node(value);
} else {
your standard recursive insertion function here
}
}
// ...
};
Long story short i've tried using shared_ptrs first, but the the insert() function will never add any element into my tree. I thought i might be doing something wrong with shareds so i tried raw pointers and i got the same non-inserty resoults.
Turns out i need to pass a reference my root/nodes.
void insert_private(int value, node*& n) {...};
I understand that if i dont pass something as reference then a copy is made. But if a pointer holds an address, doesnt it's copy hold the same address? if i make a new() to a non-referenced pointer why doesnt it stick to my root/nodes?
The why is my question here, i can accept it that it works like this, my tree works, but i dont know why its like this.
edit: After reading the comments i created this small expert level program:
void fn(int* i){
cout << "Address of local in fn before change: " << i << endl;
i = new int(2);
// so basically here we made a new int, and i will get the address of
// this integer and will point to there, what we passed on before
// becomes irrelevant
cout << "Address of local in fn after change: " << i << endl;
}
void fn2(int **i){
cout << "Address of local in fn2 before change: " << i << endl;
*i = new int(2);
cout << "Address of local in fn2 after change: " << i << endl;
}
int main(){
int* p = nullptr;
cout << "Address of p: " << p << endl;
fn(p);
cout << "p& is: " << &p << endl;
fn2(&p);
cin.get();
return 0;
};
Thank you, everyone, for the answers, it helped a lot. random.org will determine who's the one who will get the approved answer thing.
Yes it's a copy and it holds the same address, but you are assigning only to the copy which is then thrown away when the function returns. The original is unaltered. That's your problem.
As an aside, IMHO, if you are altering the value of a parameter, you should use a pointer, hence a pointer to a pointer in your case. It makes it much more obvious to the reader that you're changing the value.
n = new node(value); is an assignment.
The pointer gets a new value. Now it points to somewhere else. The pointer was passed by value, so the calling code won't see any change - the assignment only had a local effect.
In insert_node you are changing what n is pointing to.
If you want that to be reflected in the caller, then you need to pass the pointer n by reference: void insert_private(int value, node*& n), although I prefer node** n as that signals to the caller of the function that the parameter value might change.
Although, since root is a class member, you can modify it directly within insert_private.
But if a pointer holds an address, doesnt it's copy hold the same address?
Sure, until you change the address held in the copy.
Your design aside to the "why?": A pointer is a normal variable. Changes made to a local copy in the callee won't be reflected on the caller side.
void foo (int a)
{ // here: a is a copy of whatever will be passed to foo
a = 2;
}
void foo2 (int &a)
{ // here: a is something like 'a local name' for the int passed to foo2
a = 3;
}
int x = 0;
foo(x); // inside foo(x), a is another int copied from x
// x still 0 here
foo2(x); // inside foo2(x), a is 'a local name' for x
// x == 3 now
Pointers behave the same way as they're just variables containing an address.
void bar (int * a)
{
a = new int;
}
void bar2(int * &a)
{
a = new int;
}
int * x = nullptr;
bar(x); // inside bar(x), a is a new pointer copied from x
// x still nullptr here
// (and memory leaking from the new without delete)
bar2(x); // inside bar2(x), a is 'a name' for the passed pointer x
// x contains memory address from a new int
delete x;
// can be deleted -> no leak

Reason to Pass a Pointer by Reference in C++?

Under which circumstances would you want to use code of this nature in c++?
void foo(type *&in) {...}
void fii() {
type *choochoo;
...
foo(choochoo);
}
You would want to pass a pointer by reference if you have a need to modify the pointer rather than the object that the pointer is pointing to.
This is similar to why double pointers are used; using a reference to a pointer is slightly safer than using pointers.
50% of C++ programmers like to set their pointers to null after a delete:
template<typename T>
void moronic_delete(T*& p)
{
delete p;
p = nullptr;
}
Without the reference, you would only be changing a local copy of the pointer, not affecting the caller.
David's answer is correct, but if it's still a little abstract, here are two examples:
You might want to zero all freed pointers to catch memory problems earlier. C-style you'd do:
void freeAndZero(void** ptr)
{
free(*ptr);
*ptr = 0;
}
void* ptr = malloc(...);
...
freeAndZero(&ptr);
In C++ to do the same, you might do:
template<class T> void freeAndZero(T* &ptr)
{
delete ptr;
ptr = 0;
}
int* ptr = new int;
...
freeAndZero(ptr);
When dealing with linked-lists - often simply represented as pointers to a next node:
struct Node
{
value_t value;
Node* next;
};
In this case, when you insert to the empty list you necessarily must change the incoming pointer because the result is not the NULL pointer anymore. This is a case where you modify an external pointer from a function, so it would have a reference to pointer in its signature:
void insert(Node* &list)
{
...
if(!list) list = new Node(...);
...
}
There's an example in this question.
I have had to use code like this to provide functions to allocate memory to a pointer passed in and return its size because my company "object" to me using the STL
int iSizeOfArray(int* &piArray) {
piArray = new int[iNumberOfElements];
...
return iNumberOfElements;
}
It is not nice, but the pointer must be passed by reference (or use double pointer). If not, memory is allocated to a local copy of the pointer if it is passed by value which results in a memory leak.
One example is when you write a parser function and pass it a source pointer to read from, if the function is supposed to push that pointer forward behind the last character which has been correctly recognized by the parser. Using a reference to a pointer makes it clear then that the function will move the original pointer to update its position.
In general, you use references to pointers if you want to pass a pointer to a function and let it move that original pointer to some other position instead of just moving a copy of it without affecting the original.
Another situation when you may need this is if you have stl collection of pointers and want to change
them using stl algorithm. Example of for_each in c++98.
struct Storage {
typedef std::list<Object*> ObjectList;
ObjectList objects;
void change() {
typedef void (*ChangeFunctionType)(Object*&);
std::for_each<ObjectList::iterator, ChangeFunctionType>
(objects.begin(), objects.end(), &Storage::changeObject);
}
static void changeObject(Object*& item) {
delete item;
item = 0;
if (someCondition) item = new Object();
}
};
Otherwise, if you use changeObject(Object* item) signature you have copy of pointer, not original one.
Refer the code below:
When we pass x as Node *x, a new variable is created with the same address passed on by the caller function.
If you modify the value pointed by the pointer, that change will be reflected in the caller function variable.
But if we change the value of the pointer itself it will not be reflected in the caller function because callee function has the copy of the passed pointer not the original pointer itself.
void increment(int *x) {
(*x)++;
x++;
cout << x << endl; // prints 0x7ffe9f8e1900
}
int main() {
int a = 10;
int *x = &a;
increment(x);
cout << *x << endl; // prints 11
cout << x << endl; // prints 0x7ffe9f8e18fc
return 0;
}
Now, check the below code:
When we pass x as Node *&x, we pass a reference of the original variable present in the caller function meaning these two variable (caller and callee root) are same, their name may differ.
if we modify the value pointer by the pointer, that change will be reflected in the caller function variable.
Now if we change the value of the pointer itself it will also be reflected in the caller function variable.
void increment(int* &x)
{
(*x) ++;
cout << *x << endl; // prints 11
x++;
cout << x << endl; // prints 0x7fffb93eba70
}
int main()
{
int a = 10;
int *x = &a;
increment(x);
cout << *x << endl; // prints garbage
cout << x << endl; // prints 0x7fffb93eba70
return 0;
}