6

This code seems to work as expected, populates an array of numbers using a single pointer

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

int main(void)
{
    int arr[4], count = 0, i;
    char *p, s[32] = "  \t  10,  15  \n  ,20,   25  , ";

    p = s;
    do {
        arr[count++] = (int)strtol(p, &p, 10);
        while (isspace(*p) || *p == ',') p++;
    } while (*p);
    for (i = 0; i < count; i++) {
        printf("%d\n", arr[i]);
    }
    return 0;
}

My question is:

It is valid to use p as param1 (source) and &p as param 2 (address of the first invalid character) in strtol?

3 Answers 3

6

Yes, it is safe. The first argument is passed by value, so strtol has a local copy that isn't affected by changes written to the second parameter.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you Klas, but what about the restrict keywords? <wikipedia> for the lifetime of the pointer, only it or a value directly derived from it (such as pointer + 1) will be used to access the object to which it points, that seems to be a problem
It would be a problem if strtol would access **endptr, but it doesn't (for the reasons I mentioned in my comment to Kirilenko's answer).
1

Yes it is safe.

Please refer to http://en.cppreference.com/w/cpp/string/byte/strtol for complete usage reference. Line 11 of the example illustrates a call using the same variable for the 1st and 2nd parameters.

1 Comment

As of May 5th 2020, example in en.cppreference.com/w/cpp/string/byte/strtol does not use the same variable for the 1st and 2nd parameters: const long i = std::strtol(p, &p_end, 10);.
1

Yes, this is valid, as you are keeping the pointer to the beginning of the string (pointer s). Consider that you have this situation:

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

int main(void)
{
    int arr[4], count = 0, i;
    char *p, *s;
    s = (char*)malloc(sizeof(char) * 15);
    strcpy(s, "  \t  10,  15  \n  ,20,   25  , ");

    p = s;
    do {
        arr[count++] = (int)strtol(p, &p, 10);
        while (isspace(*p) || *p == ',') p++;
    } while (*p);
    for (i = 0; i < count; i++) {
        printf("%d\n", arr[i]);
    }
    free(s);
    return 0;
}

strtol will move p pointer to somewhere in string. If you call free(p) you will have memory leak (if it doesn't fail). But, since you are keeping s pointer, you will always be able to free the occupied memory.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.