lord.garbage
lord.garbage

Reputation: 5970

Is setting pointer to NULL and emptying the char array required here?

In the following code snippet I'm taking two inputs from stdin using fgets() and strtol. The two inputs get saved in different variables. In order to read in the user input I need a couple of variables for fgets() and strtol(). Here is a verbose solution using different variables for the two calls to fgets() and strtol():

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {

    long int m_row;
    long int n_col;

    char rows_save[sizeof(long int)];
    char *ptr_rows_save;
    printf("Enter number of rows:\n");
    if (fgets(rows_save, sizeof(rows_save), stdin) != NULL)
    {
        m_row = strtol(rows_save, &ptr_rows_save, 10);

    }

    char cols_save[sizeof(long int)];
    char *ptr_cols_save;
    printf("Enter number of columns:\n");
    if (fgets(cols_save, sizeof(cols_save), stdin) != NULL)
    {
        n_col = strtol(cols_save, &ptr_cols_save, 10);

    }
    return EXIT_SUCCESS;
}

As you can see, I am using a new array and a new pointer to an array for each number the program receives from stdin. I tried avoiding this for exercise purposes (or for fun for that matter). To achieve this I am using a single char array and a single pointer to an array but keeping the two separate calls to fgets() and strtol():

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {

    long int m_row;
    long int n_col;

    char save[sizeof(long int)];
    char *ptr_save;
    printf("Enter number of rows:\n");
    if (fgets(save, sizeof(save), stdin) != NULL)
    {
        m_row = strtol(save, &ptr_save, 10);
        ptr_save = NULL;
        save[0] = '\0';
    }

    printf("Enter number of columns:\n");
    if (fgets(save, sizeof(save), stdin) != NULL)
    {
        n_col = strtol(save, &ptr_save, 10);
        ptr_save = NULL;
        save[0] = '\0';
    }
    return EXIT_SUCCESS;
}

To be on the safe side, I set the pointer *ptr_save to NULL and cleared the character array by setting the first element to \0 after I have read in the user input and processed it with strtol(). But would the code be equally safe if I did not set the pointer to NULL and cleared the character array? (For those wondering, the user input will be checked later on in the code.)

Upvotes: 2

Views: 74

Answers (2)

Iskar Jarak
Iskar Jarak

Reputation: 5325

You should read the documentation for strtol() and fgets().

Since you are not actually using endptr (ptr_save, I mean), there is no point setting it to NULL... and you are (correctly) passing &ptr_save to strtol(), so strtol() won't care that you set ptr_save to NULL. In fact, in the example given where you are not doing anything with ptr_save, you could just pass NULL directly to strtol() and not use a variable... however, you should use ptr_save properly and check what it points afterwards to to verify the results of strtol(). You should also be clearing errno before each strtol() call and checking it afterwards - this is the only way to detect range and base errors.

fgets() does not care about NULLs, leading or otherwise, in the buffer, and if something goes wrong during the call there is no guarantee your leading NULL will still be there. You should check the result of fgets() to see if it succeeded or failed, not gamble on a NULL remaining at the start of the buffer.

Also, sizeof(long int) returns the number of bytes taken by a long... which is not the maximum number of characters required to represent a long in base 10.

Last, within the scope of this function, ptr_save will be valid after a successful strtol() and save will be correctly null-terminated after a successful fgets()... so provided you check the results, there is no safety gained by writing nulls in either case.

Upvotes: 3

Daij-Djan
Daij-Djan

Reputation: 50129

setting a pointer to nil doesn't destroy the memory it points to. you only 'abadon' it. In this case though your points points to your char[] anyway WHICH is memory allocated on the stack and so it gets freed when you leave the function.

depending on your needs that may be ok?!

Upvotes: 0

Related Questions