strtol reusing param
Asked Answered
V

3

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?

Velmaveloce answered 19/12, 2012 at 11:59 Comment(0)
E
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.

Equitable answered 19/12, 2012 at 12:10 Comment(1)
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);.Dishwasher
L
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.

Lamia answered 19/12, 2012 at 12:16 Comment(2)
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 problemVelmaveloce
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).Skyjack
S
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.

Storey answered 19/12, 2012 at 12:6 Comment(0)
E
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.

Equitable answered 19/12, 2012 at 12:10 Comment(1)
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);.Dishwasher

© 2022 - 2024 — McMap. All rights reserved.