COSC 2P91 Dynamic allocation Week 4a Brock University Brock - - PowerPoint PPT Presentation

cosc 2p91
SMART_READER_LITE
LIVE PREVIEW

COSC 2P91 Dynamic allocation Week 4a Brock University Brock - - PowerPoint PPT Presentation

COSC 2P91 Dynamic allocation Week 4a Brock University Brock University (Week 4a) Dynamic allocation 1 / 22 Before we begin... Two quick addenda to last week... Brock University (Week 4a) Dynamic allocation 2 / 22 Pointers to local


slide-1
SLIDE 1

COSC 2P91

Dynamic allocation Week 4a

Brock University

Brock University (Week 4a) Dynamic allocation 1 / 22

slide-2
SLIDE 2

Before we begin...

Two quick addenda to last week...

Brock University (Week 4a) Dynamic allocation 2 / 22

slide-3
SLIDE 3

Pointers to local variables accessed outside of call...

Remember how I said not to return a pointer to a local variable from a function? That was because the variable may no longer exist after the stack frame has been deallocated However, I forgot to mention one obvious case where it’ll still exist:

◮ A static member will obviously still exist ◮ e.g. to a static array (say to use as an intermediate buffer). It’s a little

  • dd, but entirely legal

Brock University (Week 4a) Dynamic allocation 3 / 22

slide-4
SLIDE 4

On declaring arrays

Particularly in parameters...

If you’ll recall, you don’t always need to fully (explicitly) define the size of arrays. For example, when passing a 2D array into a function, only the number of columns needs to be specified However, in general, you might like to explicitly use a variable for a variable length array... Further to this, you could wish to declare this variable in a later parameter than the array... Only rely on this being in Gnu C, but you can always use a parameter forward declaration e.g. void doStuff(int r,c; int stuff[r][c], int r, int c)

Brock University (Week 4a) Dynamic allocation 4 / 22

slide-5
SLIDE 5

Dynamic allocation

We’ve already looked at static declarations. We know how to create arrays, variables, etc. Basically, any time we know our precise storage requirements in advance, we’re good. And that’s why, in every other language, we only ever use arrays. For

  • everything. ... right?

Obviously not. We need some method of asking for additional memory when needed Sometimes we’ll be asking for an array of unknown dimensions

◮ Or we may simply want a ragged array

Sometimes we’ll want to be able to create larger dynamic structures

◮ e.g. lists, trees, etc.

Memory is dynamically allocated from the heap

Brock University (Week 4a) Dynamic allocation 5 / 22

slide-6
SLIDE 6

Memory allocation

The basics

We’ll look at the functions that provide memory allocation in just a

  • moment. Let’s just make sure we have a rough understanding of the

principle first... A memory allocation function sets aside some memory from the heap, and then returns a pointer to the first position of the allocated space

◮ Because the same function is used for allocation of any type, it returns

a void pointer, which can then be (implicitly or explicitly) cast

This should be self-evident by now, but be careful with pointers. Avoid unnecessary math, and always be careful whenever directly manipulating memory Memory can be allocated for an array, or a single variable

◮ If the latter seems unlikely, consider structs (particularly linked

together)

Be really careful with memory safety!

◮ It can be easy to accidentally exceed the allocated bounds of an array ◮ Similarly, remember to definitely allocate, and not simply declare the

pointer

⋆ (cough) Brock University (Week 4a) Dynamic allocation 6 / 22

slide-7
SLIDE 7

Memory allocation

malloc

The basic memory allocation function is malloc. It simply allocates a block of some designated size, and returns a corresponding pointer. Like the other three functions, part of stdlib.

i n t ∗ var ; // Pointer to a s i n g l e i n t e g e r ? f l o a t ∗ v a r r y ; // Pointer to a s i n g l e f l o a t var=malloc ( s i z e o f ( i n t ) ) ; // I m p l i c i t void ∗ −> i n t ∗ v a r r y=malloc ( s i z e o f ( i n t ) ) ; // I m p l i c i t void ∗ −> i n t ∗ . . . huh .

Explicitly casting the pointer may at least give you a warning

Brock University (Week 4a) Dynamic allocation 7 / 22

slide-8
SLIDE 8

Memory allocation

malloc (cont)

To create an array, simply tell it that you need more space:

i n t ∗ a r r =( i n t ∗) malloc ( s i z e o f ( i n t )∗ s i z e ) ;

You can access the new space like any other array now It’s worth noting that malloc doesn’t initialize the memory, so you may have junk data until you clear it out yourself. If the requested memory isn’t available, a null pointer (0) is returned instead.

Brock University (Week 4a) Dynamic allocation 8 / 22

slide-9
SLIDE 9

Memory allocation

calloc

calloc differs from malloc in two fundamental ways: It initializes allocated space to all zeroes It takes two parameters:

◮ One for the number of elements ◮ One for the size of each element Brock University (Week 4a) Dynamic allocation 9 / 22

slide-10
SLIDE 10

Memory allocation

realloc

Suppose you allocated for 10 elements, and now realize you really need space for 11. realloc lets you reallocate memory to expand (or shrink) the dynamic array. Note that, particularly if expanding the array, it may be necessary to move the location of the allocated space. As such, realloc returns a pointer to the new address of the reallocated space

◮ If you had more than one pointer to the array, then they can very easily

fall out of sync

◮ This is one of the reasons why you may wish to try to avoid realloc

altogether

realloc will, of course, preserve those values that are common to both sizes

Brock University (Week 4a) Dynamic allocation 10 / 22

slide-11
SLIDE 11

Memory allocation

We good?

Do we need any other examples? Possibly returning a dynamic array from a function?

Brock University (Week 4a) Dynamic allocation 11 / 22

slide-12
SLIDE 12

Memory deallocation

So, what do you do when you’re done with the requested memory? Of course, the memory will be reclaimed after the program exits...

◮ After all, if we had enough memory to allocate it, and if it was ever

necessary for the program, then surely we don’t have to worry about memory constraints, right?

Obviously, we’re going to need to be able to reclaim the memory sooner. For that, we use free Simply provide free with the same pointer you’ve been using

◮ Try not to putz around with this one (particularly when using pointer

arithmetic)

Note: free is not recursive!

Brock University (Week 4a) Dynamic allocation 12 / 22

slide-13
SLIDE 13

Importance of free

Because we can’t all get away with being Mozilla...

Why is it important to free? Why does it matter that free isn’t recursive? Do you know what a memory leak is?

◮ Example time! Brock University (Week 4a) Dynamic allocation 13 / 22

slide-14
SLIDE 14

Multidimensional arrays

We’ve already discussed 2D arrays a bit. Have we talked about the difference between int dealie[][] and int *dealie[]? Technically, arrays of pointers are slightly different, even if they’re generally used the same.

Brock University (Week 4a) Dynamic allocation 14 / 22

slide-15
SLIDE 15

Multidimensional arrays

Ragged arrays

Taking advantage of this knowledge, we can easily creat ragged arrays. Were I to say it was essentially the same as the Java approach, would we still need an example?

Brock University (Week 4a) Dynamic allocation 15 / 22

slide-16
SLIDE 16

Function pointers

We’ve discussed having pointers to variables, to structs, and to arrays, but we’ve left something out: pointers to functions It may not initially seem to be of obvious benefit, but function pointers can have several uses: Invoking a single block of code on data, but allowing it to have a different behaviour/outcome

◮ e.g. comparators, operators, intersections, etc.

Providing callbacks to a library Some more... creative uses (next slide) Usage is pretty simple:

returnType (∗ localName )( paramTypeA , paramTypeB )

This type of declaration can be used for parameters or variables; you can even embed the pointers inside structs!

Brock University (Week 4a) Dynamic allocation 16 / 22

slide-17
SLIDE 17

Function pointers

Fancier uses

As mentioned, you can include function pointers inside structs. Why would you do this? Gee, if only one could think of a reason for a record to have not only per-instance variables, but also associated procedures...

◮ Besides that, one could combine this concept with what we saw in our

code example to simulate basic notions of polymorphism and inheritance (and such)

◮ If you want a struct to be able to operate on itself, via its own

functions, you should probably include a reference to itself as one of the parameters

Brock University (Week 4a) Dynamic allocation 17 / 22

slide-18
SLIDE 18

Basic data structures

We should already know enough by now to be able to simulate most of the simpler data structures we’ve learned in other courses.

Brock University (Week 4a) Dynamic allocation 18 / 22

slide-19
SLIDE 19

Basic data structures

Stacks

How could we implement a stack? Actually, didn’t we already look at some code that seemed a bit familiar... Depending on why you’re creating it, you may wish to:

◮ Simply create code for a single type of stack — e.g. int ◮ Write separate stack code for multiple types ◮ Employ void pointers since the data itself doens’t affect the push/pop

behaviour

⋆ Of course, this puts the burden of type safety onto the client Brock University (Week 4a) Dynamic allocation 19 / 22

slide-20
SLIDE 20

Trees

The textbook uses trees as an example for explaining structs and

  • pointers. It’s definitely worth a read.

The only thing that’s really different from the stack is that we’re typically more interested in binary search trees, and that of course implies some notion of comparison

◮ You may wish to consider writing a comparator for whatever type it is

you’re storing, and then include it via function pointers

◮ You probably won’t be able to completely guard against improper use,

but still try to write generalized functions that take care of the finer details

⋆ That is, write separate functions to handle everything, so that all

interactions with the tree are via those functions, rather than low-level memory management and pointer tomfoolery

Brock University (Week 4a) Dynamic allocation 20 / 22

slide-21
SLIDE 21

Abstract Data Types

ADTs

We aren’t quite to the point of Abstract Data Types yet. Rather, I just want you to think about what would be necessary to implement them: Can we easily enforce type safety? If so, how? How do we reliably use the same code for multiple instances of the same ADT? How do we write it to not be tedious for a client program to use?

◮ Are there any conventions we should use? Brock University (Week 4a) Dynamic allocation 21 / 22

slide-22
SLIDE 22

Questions?

Comments?

Complaints?

Brock University (Week 4a) Dynamic allocation 22 / 22