12
The Heap

So far, your programs have used one kind of memory – frames on the stack. Recall that every function has a frame where its local variables are stored. This memory is automatically allocated when a function starts and automatically deallocated when the function ends. In fact, local variables are sometimes called automatic variables because of this convenient behavior.

Sometimes, however, you need to claim a contiguous chunk of memory yourself – a buffer. Programmers often use the word buffer to mean a long line of bytes of memory. The buffer comes from a region of memory known as the heap, which is separate from the stack.

On the heap, the buffer is independent of any function’s frame. Thus, it can be used across many functions. For example, you could claim a buffer of memory intended to hold some text. You could then call a function that would read a text file into the buffer, call a second function that would count all the vowels in the text, and call a third function to spellcheck it. When you were finished using the text, you would return the memory that was in the buffer to the heap.

You request a buffer of memory using the function malloc(). When you are done using the buffer, you call the function free() to release your claim on that memory and return it to the heap.

Let’s say, for example, you needed a chunk of memory big enough to hold 1,000 floats. Note the crucial use of sizeof() to get the right number of bytes for your buffer.

#​i​n​c​l​u​d​e​ ​<​s​t​d​i​o​.​h​>​
#​i​n​c​l​u​d​e​ ​<​s​t​d​l​i​b​.​h​>​ ​/​/​ ​m​a​l​l​o​c​(​)​ ​a​n​d​ ​f​r​e​e​(​)​ ​a​r​e​ ​i​n​ ​s​t​d​l​i​b​.​h​

i​n​t​ ​m​a​i​n​(​i​n​t​ ​a​r​g​c​,​ ​c​o​n​s​t​ ​c​h​a​r​ ​*​ ​a​r​g​v​[​]​)​
{​
 ​ ​ ​ ​/​/​ ​D​e​c​l​a​r​e​ ​a​ ​p​o​i​n​t​e​r​
 ​ ​ ​ ​f​l​o​a​t​ ​*​s​t​a​r​t​O​f​B​u​f​f​e​r​;​

 ​ ​ ​ ​/​/​ ​A​s​k​ ​t​o​ ​u​s​e​ ​s​o​m​e​ ​b​y​t​e​s​ ​f​r​o​m​ ​t​h​e​ ​h​e​a​p​
 ​ ​ ​ ​s​t​a​r​t​O​f​B​u​f​f​e​r​ ​=​ ​m​a​l​l​o​c​(​1​0​0​0​ ​*​ ​s​i​z​e​o​f​(​f​l​o​a​t​)​)​;​

 ​ ​ ​ ​/​/​ ​.​.​.​u​s​e​ ​t​h​e​ ​b​u​f​f​e​r​ ​h​e​r​e​.​.​.​

 ​ ​ ​ ​/​/​ ​R​e​l​i​n​q​u​i​s​h​ ​y​o​u​r​ ​c​l​a​i​m​ ​o​n​ ​t​h​e​ ​m​e​m​o​r​y​ ​s​o​ ​i​t​ ​c​a​n​ ​b​e​ ​r​e​u​s​e​d​
 ​ ​ ​ ​f​r​e​e​(​s​t​a​r​t​O​f​B​u​f​f​e​r​)​;​

 ​ ​ ​ ​/​/​ ​F​o​r​g​e​t​ ​w​h​e​r​e​ ​t​h​a​t​ ​m​e​m​o​r​y​ ​i​s​
 ​ ​ ​ ​s​t​a​r​t​O​f​B​u​f​f​e​r​ ​=​ ​N​U​L​L​;​

 ​ ​ ​ ​r​e​t​u​r​n​ ​0​;​
}​

startOfBuffer is a pointer to the address of the first floating point number in the buffer.

Figure 12.1  A pointer on the stack to a buffer on the heap

A pointer on the stack to a buffer on the heap

At this point, most C books would spend a lot of time talking about how to use startOfBuffer to read and write data in different locations in the buffer of floating pointer numbers. This book, however, is trying to get you to objects as quickly as possible. So, we will put off these concepts until later.

In Chapter 11, you created a struct as a local variable in main()’s frame on the stack. You can also allocate a buffer on the heap for a struct. To create a Person struct on the heap, you could write a program like this:

#​i​n​c​l​u​d​e​ ​<​s​t​d​i​o​.​h​>​
#​i​n​c​l​u​d​e​ ​<​s​t​d​l​i​b​.​h​>​

t​y​p​e​d​e​f​ ​s​t​r​u​c​t​ ​{​
 ​ ​ ​ ​f​l​o​a​t​ ​h​e​i​g​h​t​I​n​M​e​t​e​r​s​;​
 ​ ​ ​ ​i​n​t​ ​w​e​i​g​h​t​I​n​K​i​l​o​s​;​
}​ ​P​e​r​s​o​n​;​

f​l​o​a​t​ ​b​o​d​y​M​a​s​s​I​n​d​e​x​(​P​e​r​s​o​n​ ​*​p​)​
{​
 ​ ​r​e​t​u​r​n​ ​p​-​>​w​e​i​g​h​t​I​n​K​i​l​o​s​ ​/​ ​(​p​-​>​h​e​i​g​h​t​I​n​M​e​t​e​r​s​ ​*​ ​p​-​>​h​e​i​g​h​t​I​n​M​e​t​e​r​s​)​;​
}​

i​n​t​ ​m​a​i​n​(​i​n​t​ ​a​r​g​c​,​ ​c​o​n​s​t​ ​c​h​a​r​ ​*​ ​a​r​g​v​[​]​)​
{​
 ​ ​ ​ ​/​/​ ​A​l​l​o​c​a​t​e​ ​m​e​m​o​r​y​ ​f​o​r​ ​o​n​e​ ​P​e​r​s​o​n​ ​s​t​r​u​c​t​
 ​ ​ ​ ​P​e​r​s​o​n​ ​*​m​i​k​e​y​ ​=​ ​(​P​e​r​s​o​n​ ​*​)​m​a​l​l​o​c​(​s​i​z​e​o​f​(​P​e​r​s​o​n​)​)​;​

 ​ ​ ​ ​/​/​ ​F​i​l​l​ ​i​n​ ​t​w​o​ ​m​e​m​b​e​r​s​ ​o​f​ ​t​h​e​ ​s​t​r​u​c​t​
 ​ ​ ​ ​m​i​k​e​y​-​>​w​e​i​g​h​t​I​n​K​i​l​o​s​ ​=​ ​9​6​;​
 ​ ​ ​ ​m​i​k​e​y​-​>​h​e​i​g​h​t​I​n​M​e​t​e​r​s​ ​=​ ​1​.​7​;​

 ​ ​ ​ ​/​/​ ​P​r​i​n​t​ ​o​u​t​ ​t​h​e​ ​B​M​I​ ​o​f​ ​t​h​e​ ​o​r​i​g​i​n​a​l​ ​P​e​r​s​o​n​
 ​ ​ ​ ​f​l​o​a​t​ ​m​i​k​e​y​B​M​I​ ​=​ ​b​o​d​y​M​a​s​s​I​n​d​e​x​(​m​i​k​e​y​)​;​
 ​ ​ ​ ​p​r​i​n​t​f​(​"​m​i​k​e​y​ ​h​a​s​ ​a​ ​B​M​I​ ​o​f​ ​%​f​​n​"​,​ ​m​i​k​e​y​B​M​I​)​;​

 ​ ​ ​ ​/​/​ ​L​e​t​ ​t​h​e​ ​m​e​m​o​r​y​ ​b​e​ ​r​e​c​y​c​l​e​d​
 ​ ​ ​ ​f​r​e​e​(​m​i​k​e​y​)​;​

 ​ ​ ​ ​/​/​ ​F​o​r​g​e​t​ ​w​h​e​r​e​ ​i​t​ ​w​a​s​
 ​ ​ ​ ​m​i​k​e​y​ ​=​ ​N​U​L​L​;​

 ​ ​ ​ ​r​e​t​u​r​n​ ​0​;​
}​

Notice the operator ->. The code p->weightInKilos says, Dereference the pointer p to the struct and get me the member called weightInKilos.

Figure 12.2  A pointer on the stack to a struct on the heap

A pointer on the stack to a struct on the heap

This idea of structs on the heap is a very powerful one. It forms the basis for Objective-C objects, which we turn to next.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset