Вы находитесь на странице: 1из 30

Programming for Engineers

Day 11

Limit Lifetime of Variables


Declare variables in the smallest scope theyre needed, not the
largest
Avoids name collision issues and bugs with unintentional re-use of the
variable
Makes code easier to follow and understand

Were not writing 1989 C

Dynamic Memory Allocation


Often dont know how much storage is needed for some data
Based on user input, runtime events, simulation input configuration, etc.

Two keywords in C++ can be used to allocate and release memory:


new used to allocate new memory for an object or array, returns a pointer to
the allocated memory
delete used to release memory allocated by new for a single object
delete[] used to release memory allocated by new for an array

Programmer is responsible for releasing memory allocated with new,


if you dont delete the memory is leaked
You will lose points on hw and your code will crash on the job

Diagram courtesy of
Gustavo Duarte:
http://duartes.org/gust
avo/blog/post/anatomy
-of-a-program-inmemory/

Memory Allocation
Stack
int *a = new int(5);

Address
a

0x0001

Heap
Value
0x0021

Address
0x0021

0x0005

0x0025

0x0009

0x0029

0x000D

0x002D

0x0011

0x0031

0x0015

0x0035

Value
5

Memory Allocation
Stack
int *a = new int(5);
int *b = new int(14);

Address

Heap
Value

Address

Value

0x0001

0x0021

0x0021

0x0005

0x0025

0x0025

14

0x0009

0x0029

0x000D

0x002D

0x0011

0x0031

0x0015

0x0035

Memory Allocation
Stack
int *a = new int(5);
int *b = new int(14);
int *c = b;

Address

Heap
Value

Address

Value

0x0001

0x0021

0x0021

0x0005

0x0025

0x0025

14

0x0009

0x0025

0x0029

0x000D

0x002D

0x0011

0x0031

0x0015

0x0035

Memory Allocation
Stack
int *a = new int(5);
int *b = new int(14);
int *c = b;

Address

Heap
Value

Address

Value

0x0001

0x0021

0x0021

0x0005

0x0025

0x0025

-62

0x0009

0x0025

0x0029

*c = -62;

0x000D

0x002D

0x0011

0x0031

0x0015

0x0035

Memory Allocation
Stack
int *a = new int(5);
int *b = new int(14);
int *c = b;

Address

Heap
Value

Address

0x0001

0x0021

0x0021

0x0005

0x0025

0x0025

0x0009

0x0025

0x0029

Value

*c = -62;
delete a;

0x000D

0x002D

0x0011

0x0031

0x0015

0x0035

-62

Memory Allocation
Stack
int *a = new int(5);
int *b = new int(14);
int *c = b;

Address

Heap
Value

Address

0x0001

0x0021

0x0021

0x0005

0x0025

0x0025

0x0009

0x0025

0x0029

*c = -62;
delete a;
delete b;
What if we wrote delete c; instead?
Does the memory we allocated on
line 2 get deleted Yes/No?

0x000D

0x002D

0x0011

0x0031

0x0015

0x0035

Value

Memory Allocation: Dangling Pointers


Stack
int *a = new int(5);
int *b = new int(14);
int *c = b;

Address

Heap
Value

Address

0x0001

0x0021

0x0021

0x0005

0x0025

0x0025

0x0009

0x0025

0x0029

*c = -62;
delete a;
delete b;
a and b point to unowned locations
in memory and thus are dangling.
Dereferencing them at this point is
undefined behavior

0x000D

0x002D

0x0011

0x0031

0x0015

0x0035

Value

Memory Allocation: Arrays


Stack
int *a = new int[3];

Address
a

0x0001

Heap
Value
0x0021

Address
0x0021

0x0005

0x0025

0x0009

0x0029

0x000D

0x002D

0x0011

0x0031

0x0015

0x0035

Value

Memory Allocation: Arrays


Stack
int *a
a[0] =
a[1] =
a[2] =

= new int[3];
4;
7;
-4;

Address
a

0x0001

Heap
Value
0x0021

Address

Value

0x0021

0x0005

0x0025

0x0009

0x0029

-4

0x000D

0x002D

0x0011

0x0031

0x0015

0x0035

Memory Allocation: Arrays


Stack
int *a
a[0] =
a[1] =
a[2] =

= new int[3];
4;
7;
-4;

int *b = a + 2;

Address

Heap
Value

Address

Value

0x0001

0x0021

0x0021

0x0005

0x0029

0x0025

0x0009

0x0029

-4

0x000D

0x002D

0x0011

0x0031

0x0015

0x0035

Memory Allocation: Arrays


Stack
int *a
a[0] =
a[1] =
a[2] =

= new int[3];
4;
7;
-4;

int *b = a + 2;
*b = 20

Address

Heap
Value

Address

Value

0x0001

0x0021

0x0021

0x0005

0x0029

0x0025

0x0009

0x0029

20

0x000D

0x002D

0x0011

0x0031

0x0015

0x0035

Memory Allocation: Arrays


Stack
int *a
a[0] =
a[1] =
a[2] =

= new int[3];
4;
7;
-4;

int *b = a + 2;
*b = 20
a[1] = -45;

Address

Heap
Value

Address

Value

0x0001

0x0021

0x0021

0x0005

0x0029

0x0025

-45

0x0009

0x0029

20

0x000D

0x002D

0x0011

0x0031

0x0015

0x0035

Memory Allocation: Arrays


Stack
int *a
a[0] =
a[1] =
a[2] =

= new int[3];
4;
7;
-4;

int *b = a + 2;
*b = 20
a[1] = -45;
delete[] a;

Address

Heap
Value

Address

0x0001

0x0021

0x0021

0x0005

0x0029

0x0025

0x0009

0x0029

0x000D

0x002D

0x0011

0x0031

0x0015

0x0035

Value

Memory Allocation: Dangling Pointers


Stack
int *a
a[0] =
a[1] =
a[2] =

= new int[3];
4;
7;
-4;

int *b = a + 2;
*b = 20
a[1] = -45;
delete a; // leak
delete[] a; // OK
a and b point to unowned locations
in memory and thus are dangling.
Dereferencing them at this point is
undefined behavior

Address

Heap
Value

Address

0x0001

0x0021

0x0021

0x0005

0x0029

0x0025

0x0009

0x0029

0x000D

0x002D

0x0011

0x0031

0x0015

0x0035

Value

Memory Allocation: Returning Large Values


Stack (main)
int* setup_array(size_t n) {
int *x = new int[n];
// fill x[] with values
return x;
}

Address
a

0x0001
0x0005

int main() {
int *a = setup_array(1000000);
// do some stuff with a
delete[] a;
return 0;
}

Value
????

Heap
Address

Value

0x000020
..
0x3d0920

Memory Allocation: Returning Large Values


Stack (setup_array)
int* setup_array(size_t n) {
int *x = new int[n];
// fill x[] with values
return x;
}

Address
x

0x000D

Value
0x000020

0x00011
int main() {
int *a = setup_array(1000000);
// do some stuff with a
delete[] a;
return 0;
}

0x0001
0x0005

Address

Value
????

Value

0x000020
..

Stack (main)
Address

Heap

0x3D0920

Memory Allocation: Returning Large Values


Stack (setup_array)
int* setup_array(size_t n) {
int *x = new int[n];
// fill x[] with values
return x;
}

Address
x

0x000D

Value
0x000020

0x00011
int main() {
int *a = setup_array(1000000);
// do some stuff with a
delete[] a;
return 0;
}

Stack (main)
Address
a

0x0001
0x0005

Value
????

Heap
Address

Value

0x000020

..

0x3D0920

1000000

Memory Allocation: Returning Large Values


Stack (setup_array)
int* setup_array(size_t n) {
int *x = new int[n];
// fill x[] with values
return x;
}

Address
x

0x000D

Value
0x000020

0x00011
int main() {
int *a = setup_array(1000000);
// do some stuff with a
delete[] a;
return 0;
}

Stack (main)
Address
a

0x0001
0x0005

Value
????

Heap
Address

Value

0x000020

..

0x3D0920

1000000

Memory Allocation: Returning Large Values


Stack (main)
int* setup_array(size_t n) {
int *x = new int[n];
// fill x[] with values
return x;
}

Address
a

0x0001
0x0005

int main() {
int *a = setup_array(1000000);
// do some stuff with a
delete[] a;
return 0;
}

Value
0x000020

Heap
Address

Value

0x000020

..

0x3d0920

1000000

Memory Allocation: Returning Large Values


Stack (main)
int* setup_array(size_t n) {
int *x = new int[n];
// fill x[] with values
return x;
}

Address
a

0x0001
0x0005

int main() {
int *a = setup_array(1000000);
// do some stuff with a
delete[] a;
return 0;
}

Value
0x000020

Heap
Address

Value

0x000020

..

0x3d0920

2000000

Memory Allocation: Returning Large Values


Stack (main)
int* setup_array(size_t n) {
int *x = new int[n];
// fill x[] with values
return x;
}

Address
a

0x0001

Value
0x000020

0x0005
int main() {
int *a = setup_array(1000000);
// do some stuff with a
delete[] a;
return 0;
Will the array we allocated on the heap
}
be deleted correctly? Yes/No?

Heap
Address

Value

0x000020

..

0x3d0920

2000000

Memory Allocation: Returning Large Values


Stack (main)
int* setup_array(size_t n) {
int *x = new int[n];
// fill x[] with values
return x;
}

Address
a

0x0001

Value
0x000020

0x0005
int main() {
int *a = setup_array(1000000);
// do some stuff with a
delete[] a;
return 0;
Will the array we allocated on the heap
}
be deleted correctly? Yes, it will

Heap
Address
0x000020
..
0x3d0920

Value

Memory Leaks
Stack
int main(){
{
int *a
a[0] =
a[1] =
a[2] =

Address
= new int[3];
4;
7;
-4;

0x0001

Heap
Value
0x0021

Address

Value

0x0021

0x0005

0x0025

0x0009

0x0029

-4

0x000D

0x002D

0x0011

0x0031

0x0015

0x0035

Memory Leaks
Stack
int main(){
{
int *a
a[0] =
a[1] =
a[2] =
int *b

Address
= new int[3];
4;
7;
-4;
= new int(16);

Heap
Value

Address

Value

0x0001

0x0021

0x0021

0x0005

0x002D

0x0025

0x0009

0x0029

-4

0x000D

0x002D

16

0x0011

0x0031

0x0015

0x0035

Memory Leaks
Stack
int main(){
{
int *a = new int[3];
a[0] = 4;
a[1] = 7;
a[2] = -4;
int *b = new int(16);
}
// Scope exits, a and b are
// not deleted so the
// memory is leaked!

Address

Heap
Value

Address

Value

0x0001

0x0021

0x0005

0x0025

0x0009

0x0029

-4

0x000D

0x002D

16

0x0011

0x0031

0x0015

0x0035

Memory Leaks
Stack
int main(){
{
int *a = new int[3];
a[0] = 4;
a[1] = 7;
a[2] = -4;
int *b = new int(16);
}
// Scope exits, a and b are
// not deleted so the
// memory is leaked!
return 0;
}
// Program exits, all
// memory is freed

Address

Heap
Value

Address

0x0001

0x0021

0x0005

0x0025

0x0009

0x0029

0x000D

0x002D

0x0011

0x0031

0x0015

0x0035

Value

Вам также может понравиться