2

How does the copy work for the dynamic variables? Why do we use a pointer to initialize them?

int* a = new int;
a = 5;
int* b = new int;
b = a;
delete a;

What does the above code do?

Level 31
  • 403
  • 3
  • 9

5 Answers5

3

Analysis:

Line #1: int* a = new int;

Variable a is set to point to a piece of dynamically-allocated memory (typically in the heap).

Line #2: a = 5;

Variable a is set to point to address 5 in memory, so you've "lost" the pointer to that piece of memory previously allocated, and you will not be able to release it later (a.k.a. memory leak).

Line #3: int* b = new int;

Variable b is set to point to a piece of dynamically-allocated memory (typically in the heap).

Line #4: b = a;

Variable b is set to point to where variable a is pointing, i.e., address 5 in memory. So once again, you've "lost" the pointer to that piece of memory previously allocated, and you will not be able to release it later.

Line #5: delete a;

An attempt to release a previously allocated piece of memory, located at address 5. This attempt will most likely cause your program to crash, due to a memory access violation, as the delete operation is guaranteed to complete successfully only for an address value returned by a previous call to a new operation of the same type.

In order to fix all the above problems, you can do the following:

  1. Change a = 5 to *a = 5

  2. Change b = a to *b = *a

  3. Add delete b after delete a

As an alternative to steps 2 and 3, you can simply change int* b = new int to int* b.

barak manos
  • 29,648
  • 10
  • 62
  • 114
1

Tear it down line by line:

int* a = new int;

Allocates an int variable on the free store and stores its address in a whose type is pointer to int.

a = 5;

You probably want to write *a = 5; instead, which assigns the value 5 to the int variable pointed to by a.

int* b = new int;

Allocates an int variable on the free stores and store its address in b whose type is pointer to int.

b = a;

You probably want to write *b = *a; instead, which assigns the value of the int variable pointed to by b to the int variable pointed to by a.
b = a; makes b point to the same int variable pointed to by a and you immediately lose track of the int variable originally pointed to by b, and it's a memory leak.

delete a;

Deallocates the int variable pointed to by a. Here you should also delete b;, otherwise it's a memory leak.

I would suggest you start from the very beginning of the concepts of pointers in C/C++ before you write any practical code.

neverhoodboy
  • 1,040
  • 7
  • 13
1

Probably you wanted to assign 5 to the address pointed by a:

*a = 5; 

then when you do

b = a; 

b is pointing the same memory pointed by a: the one containing 5.

When you

delete a;

you free the memory pointed by both a and b.

At this point you leaked the memory initially pointed by b.

As a rule of thumb each new as to be matched by a delete.

But you probably wanted to do the following:

int* a = new int;
*a = 5;
int* b = new int;
*b = *a;
delete a;
delete b;

meaning that you allocate the memory for *a then assign 5 to *a, allocate the memory for *b, copy *a on *b and free the memory.

jimifiki
  • 5,377
  • 2
  • 34
  • 60
1

We use pointers to access memory on the heap - that is memory that does not disappear when the function returns.

Your b = a does not copy the contents of that memory, instead it makes that:

1) the second heap memory you created is no-longer reachable

2) both variables a and b now refer to the same memory which was created in your first line.

delete a then frees that memory. It should no-longer be used (a and b now point to something you should not use). The memory allocated in your third line is never freed (so it is 'leaked').

Bernd Elkemann
  • 23,242
  • 4
  • 37
  • 66
1

Your code does not even compile because your second row is wrong. It might work with some compiler flags tho

error: invalid conversion from 'int' to 'int*'

What you probably want is:

int* a = new int;
*a = 5;
int* b = new int;
b = a;
delete a;

Think of the pointers this way:

Variable name | Memory address | Value
1.st line
a | 1000 | 2000 //pointer a at address 1000 points to address 2000 on heap
/ | 2000 | /    //int on address 2000 with undefined value

2nd line
/ | 2000 | 5    //set the value at the memory pointed by a to 5

3rd line
b | 1004 | 2500 //another pointer pointing to another int on heap
/ | 2500 | /

4th line
b | 1004 | 2000 //b now points to the address that a is pointing to

5th line
Deallocates memory at address 2000

On 4th line you just got a memory leak because you lost the pointer to your second int.

Why use pointers? Because when you pass variables to functions their value get's copied and this can be an expensive operation. For example:

void func(HugeObject ho) {
  //do something
}
main() {
  HugeObject ho();
  func(ho);
}

The whole HugeObject will be copied to the function. Since this is a lot of memory it's expensive operation. With pointers this is not an issue:

void func(HugeObject * ho) {
  //do something
}
main() {
  HugeObject * ho = new HugeObject();
  func(ho);
  delete ho;
}

If we use pointers we only copy 32 or 64bit address instead of the whole object.

Generally speaking, passing ints around your code is a bad idea because you get all the problems of pointers and no benefits. In fact, on 64bit machine you would be using more memory to pass pointers than passing ints since int is usually 32bit.

PS: I am no C++ expert so if I you see a glaring mistake please do correct me. I don't want to spread any misinformation.

cen
  • 2,873
  • 3
  • 31
  • 56