Home > Software design >  string doesn't "rewind" itself when accessing via pointer
string doesn't "rewind" itself when accessing via pointer

Time:10-31

char    *ft_between(char *str, size_t from, size_t to)
{
    char *between;

    between = malloc(16);
    while ((from >=0) && (from < to) && (to < ft_strlen(str)))
    {
        *(between  ) = str[from  ];
    }
    *between = '\0';
    printf("%s\n", between); // print nothing
    printf("%s\n", between - 16); // print between but never had to do this before...
    return (between);// even on calling function the pointer still at end of string
}

I think it's because I changed the address of between using but I usually do that and never had this behavior... is that because of malloc ???

Is there someting I missed ? Is thear a way to "rewind" the string lol If I do it via a counter ie. between[counter ] = str[from ]; it works but I wanted to do via pointers as it's faster... from what I've red !

in this example str is itterate with until the end to add char but when return in calling function a printf will print all str

void    ft_nbr2str(char *str, size_t nbr, char *base, size_t base_len)
{
    if (nbr >= base_len)
    {
        ft_nbr2str(str, (nbr / base_len), base, base_len);
        while (*str != '\0')
            str  ;
        *str = base[nbr % base_len];
    }
    else
        *str = base[nbr];
}

CodePudding user response:

I think it's because I changed the address of between using

It's because you modified the value of between via the operator. That value is the address of something else. The address of between or any other object cannot be modified.

but I usually do that and never had this behavior.

The behavior you describe is absolutely normal, so either no, you don't usually do that, or yes you did have that behavior. In your code, you will observe the same effect on from. I really don't fathom why immediately after you execute *between = '\0'; you would expect printf("%s\n", between) to print a non-empty string. malloc has nothing in particular to do with it.

I speculate that in other cases you may have instead modified a copy of your pointer, which, naturally, does not modify the original pointer. Possibly you did this by passing your pointer (by value) to another function. Example:

void strcpy_range(char *dest, char *src, size_t from, size_t to) {
    while ((from >=0) && (from < to) && (src[from] != '\0'))
    {
        *(dest  ) = src[from  ];  // dest is modified
    }
    *dest = '\0';
}

char    *ft_between(char *str, size_t from, size_t to)
{
    char *between = malloc(16);

    strcpy_range(between, str, from, to);

    printf("%s\n", between); // prints the extracted substring
    return between;          // returns a pointer to the extracted substring
}

If you want to rescue your original version without introducing a new function, then use a temporary variable to track the current location in the substring. For example,

char    *ft_between(char *str, size_t from, size_t to)
{
    char *between = malloc(16);
    char *temp = between;
    while ((from >=0) && (from < to) && (to < ft_strlen(str)))
    {
        *(temp  ) = str[from  ];
    }
    *temp = '\0';
    printf("%s\n", between); // prints the extracted substring
    return between;          // returns the extracted substring
}

Addendum

The alternative example added to the question demonstrates exactly the form I speculated you might have used. The (non-)effect on the caller's copy of the pointer is not analogous to or even related to the effect on the function parameter during execution of the function.

CodePudding user response:

After you've incremented the pointer, it now points to a different region of memory. Since the pointer is of type char, summing one unit is the same as summing sizeof(char) units, which turns out to still be 1; to 'rewind' it, as you say, you'd just have to subtract 16 * sizeof(char) = 16 (notice you're dereferencing the pointer summed by 16, so it makes perfect sense to subtract 16 to get it back to its position, or subtract however many times you want so that it points to the location you expect it to)

CodePudding user response:

After this statement

*between = '\0';

the pointer between points to an empty string. So this call of printf:

printf("%s\n", between); // print nothing

indeed will output nothing.

And this return statement

return (between);// even on calling function the pointer still at end of string

returns this pointer to an empty string.

Pay attention to that this condition

(from >=0)

does not make sense because objects of the unsigned type size_t can not be negative.

Also it is unclear why there is used the magic number 16

between = malloc(16);

and

printf("%s\n", between - 16); // print between but never had to do this before...

And the function should not output any message. It is the caller of the function that will decide whether to output something.

The function can be declared and defined the following way

char * ft_between( const char *str, size_t from, size_t to )
{
    char *between;

    size_t n = ft_strlen( str );

    if ( n < to ) to = n;

    if ( to <= from )
    {
        between = calloc( 1, sizeof( char ) );
    }
    else
    {  
        between = malloc( to - from   1 );
        if ( between != NULL )
        {
            char *p = between;
            while ( from != to ) *p   = str[from  ];
            *p = '\0';
        }
    }

    return between;
}  
  • Related