Avoid dereferencing NULL


#1

Hi there

I have real difficulties understanding this chapterl. It seemed to me that the codes here don’t do anything. And even if doesn’t make sense to me. Why there’s only a b[/b] after if ? Does if even work this way? or did I miss something important??


#2

Indeed, this is a difficult chapter.

We’re happy to answer specific questions about the meaning of certain code snippets and bits of the prose, so feel free to ask!

To your question about fPtr:

if (fPtr) { // do something with fPtr }

is the exact same (just shorthand) as:

if (fPtr != NULL) { // do something with fPtr }

That is, both examples just check to see if fPtr has a non-NULL value.


#3

For what it’s worth, pointers are hard for everyone. Wrapping one’s head around what a pointer is and how it works takes lots of practice for any developer. The good news is, it’s mostly downhill afterward. Take your time, and don’t be afraid to ask questions and even push on to the next chapters if necessary. You can always come back.


#4

Hello,

Please can you help, this section doesn’t seem clear again. I have as you requested some very specific terms/sections I needed clairfied and could really appreciate the help.

I think I get the basic concept of a NULL Pointer {a pointer to an address that doesn’t actually ‘exist’ but can be referenced anyhow}

I think I understand the below {a function can return many or different values when called}

Sometimes a function can supply many values by reference, but you may only care about some of them.

This below the bit that first really confused Does it mean that if I have a function that for instance calculates feet and inches from metres. But I don’t need the inches value only only the feet, "how can I avoid declaring the inches value?

How do you avoid declaring these variables and passing their addresses when you are not going to use them anyway?

Again really unclear here below. (

Typically, you pass NULL as an address to tell the function “I do not need this particular value.”
This means that you should always check to make sure the pointers are non-NULL before you dereference them. Add these checks in metersToFeetAndInches():

Look forward to help.

Please ELI5.


#5

I might be able to help you out. So first off, you can think of functions in the same way they are used in math. Do you remember something like this… f(x) = x * x. And then input a value f(3) = 9. That’s how functions work in C, in fact we almost use the same language… we might define: int func(x) {return x * x;} and then call that by saying ret_val = func(var) or 9 = func(3);. You can define the function any way you want. You send it a value, and the function returns a value. So we send this particular function 8, it returns 64. Get it? The problem is that with this model, a function can only return one value. What if we want to return two values? Well… now we have to get into pointers. Pointers are just that, a thing that points to another thing. In theory, we will create two pointers, we will send those pointers to the function, the function will set what the pointers point to with some values, and when we are back in our main() program, we can now access the values of those things the pointers pointed to. It’s the magic way of getting a function to essentially return for us two or more values. However… pointers are dangerous. There are three important steps to working with pointers… 1) create the pointer (int *p;) 2) have the pointer point to something (p = &inches;) 3) typically you would use the pointer to change the value of the thing it’s pointing to (*p = 12;). However, if you skip step 2… you may be in trouble. When you created the pointer in step 1… you have no idea where it’s pointing to… and if you proceed immediately to step 3… you are overwriting some random section of memory. So the standard protocol is when creating a pointer, always initialize it by pointing it to NULL, in fact you can combine steps 1 and 2 … int *p = NULL;. That way, if you ask for the value to change before assigning the pointer to something, you won’t inadvertently write over something unintentionally. And yes… back in your code, check to see if the pointer is no longer NULL before using it. Hope that helps!


#6

Thank you very much maark600. Getting there… the last section seemed to help most in understanding this…

Can someone please clairfy why we seemed to have duplicated 2 lines/actions we already had in code? It is the line with if() function and printf() as below:

if (ftPtr) {
    printf(" Storing %u to the address %p \n\n", feet, ftPtr);
    *ftPtr = feet; }

Previously though we already had similar code in the function.

printf(" Storing %u to the address %p \n\n", feet, ftPtr);
*ftPtr = feet;

MikeyWard earlier mentioned that the if() function is to

{ // do something with fPtr }

Can anyone please clairfy why the if() function was used here—ELI5 thanks.

PS maark6000’s comment which helped most is below—edited a bit for clarity. I am still reviewing it but I partly thought all the 3 check steps you mentioned already were in the original convertMetersToFeetAndInches code?

There are three important steps to working with pointers…

    1. create the pointer (int *p;)
    1. have the pointer point to something (p = &inches;)
    1. typically you would use the pointer to change the value of the thing it’s pointing to (*p = 12;).

However, if you skip step 2… you may be in trouble.

When you created the pointer in step 1 you have no idea where it’s pointing to and if you proceed immediately to step 3 you are overwriting some random section of memory.

So the standard protocol is when creating a pointer, always initialize it by pointing it to NULL, in fact you can combine steps 1 and 2 … int *p = NULL;.


#7

The book is explaining that you should use the conditional if() statement to make sure the value you are about to use has actually been set in the function. It shows the before and after code… which is why it’s repeated… the after now contains the conditional if() statement checking to see if the pointer has been set, or if it is NULL (remember, if it’s NULL, that section of code within the {} does not get executed). The book goes on to explain how to use setting a pointer to NULL as a way of indicating that you won’t need that variable to accomplish your goals. Functions and pointers are the two hardest concepts to understand in C programming, and here they are being intertwined! Because this book is about Objective-C, I can understand why pointers and functions aren’t given more explanation… but if these concepts are still fuzzy to you I suggest “C Primer Plus” by Stephen Prata… therein is a detailed explanation of both concepts and some very challenging exercises that will help cement these concepts in your mind.


#8

if () is not a function; it is a statement, a conditional statement to be more precise. The if statement takes a condition expression and a statement and executes that statement if the value of the condition expression is not zero.

Syntax:

if (condition-expression) statement optional-else-statement

Some concrete examples will help.

Example 1: no else part

if (0) {
   // statements in this block never execute
   ...
}

Example 2: no else part

if (1) {
   // statements in this block always execute
   ...
}

Example 3:

if (currentRoomTemperature () < 17) {
    if (heaterIsOff ())
        turnOnHeater ();
}
else {
    if (heaterIsOn ())
        turnOffHeater ();
}

#9

Thank you also ibex10


#10

Thanks—I think I might have it!

1. Firstly currently in my code I have something like this:

if (ftPtr) {
    printf(" NEW.1 Storing %u to the address %p \n\n", feet, ftPtr);
    *ftPtr = feet; }

printf(" Storing %u to the address %p \n\n", feet, ftPtr);

Question: Do I really need the 2nd/repeated line? (As below)—does’t the previous if() statement do this already?

printf(" Storing %u to the address %p \n\n", feet, ftPtr);

2. Secondly can I confirm my understanding at a high level:

We test if a pointer exists (is not null) before we dereference it’s contents/data by using the if() statement.

The if() statement will not carry out the action (in this case storing feet to the ftPtr) unless it has first been established as ftPtr already existing first.

Fingers crossed I have understood it. )


#11

looking good. correct, you don’t need the second line, it was showing before and after. Don’t need both.