C - String Reversal Function with Pointers Not Running

Viewed 72

I understand that issues with string-reversal in C are numerous on this site, but I seem to be having a uniquely odd problem: the reversal logic simply does not run despite seeming to be set up correctly. I wanted to write a program to reverse a given string in-place, by moving two pointers from the front and back of the string together:

void reverse_inplace_pointer(char *string_in, int length) {
    char *back_ptr = string_in + (length - 1);

    for (int i = 0; i < length / 2; i++) {
        char swap_char = *back_ptr;

        /* Dereference pointers to double-check values */
        printf("\nCurrent front char: %c\nCurrent back char: %c", *string_in, *back_ptr);
        
        /* Swap */
        *back_ptr  = *string_in;
        *string_in = swap_char;
        printf("\nSwap %u successful.", i + 1);
    
        string_in++;
        back_ptr--;
    } 
}

Calling this with a test string: char *test_string = "TestMeTestMe"; nets the result:

Current front char: T
Current back char: e

And then execution just stops, at the assignment of the character pointed to by *string_in to the location pointed to by *back_ptr. If I remove the assignment, the program will quite happily move the pointers along the test string and print out each character without issue.

I looked for other examples of reassigning elements in arrays and found the logic in tutorials to be almost identical to mine. I copied this example wholesale as a test:

void steal_this_function(char *string) {
    printf("\nEntering function:");
    int length, c;
    char *begin, *end, temp;

    length = strlen(string);

    begin = string;
    end = string;

    for (c = 0; c < (length - 1); c++) {
        end++;
    }

    for (c = 0; c < length / 2; c++) {
        temp = *end;
        *end = *begin;
        *begin = temp;

        begin++;
        end--;
    }
}

The result is the same - it stops on the first iteration and the program exits. The only difference here is the reuse of the original pointer string, which is then walked to the end of the string with a for-loop.

Clearly I have some confusion here with pointers, but my understanding was that *back_ptr = *string_in; effectively says dereference the pointer string_in, then go to the location pointed to by back_ptr and store whatever it contains there.

I'm also compiling with the -Wall flag on GCC and it isn't finding any issues. This is frustrating because it should be very simple.

2 Answers

the function requires modifiable char array. It cannot be called when parameter is a pointer to thestring literal.

Some additional remarks.

  1. This kind of function should return the reversed string. It is possible to use it as a parameter of another functions.
  2. strlen returns size_t not int. Use the correct type in the loops as well
#include <string.h>
#include <stdio.h>

char *reverse(char *str)
{
    char *end = str + strlen(str) - !!*str;
    char *wrk = str;

    while(end > wrk)
    {
        char tmp = *wrk;
        *wrk++ = *end;
        *end-- = tmp;
    }
    return str;
}

int main(void)

{
    char str[] = "0123456789";

    printf("%s\n", reverse(str));
}

Calling this with a test string: char *test_string = "TestMeTestMe";

That's the culprit, as noted in the comments, it declares a pointer to the memory where the string literal "TestMeTestMe" is stored, which you are not allowed to modify.

You should declare an array instead.

char test_string[] = "TestMeTestMe"; // Now test_string is a modifiable
                                     // NULL-terminated char[13]

I'm also compiling with the -Wall flag on GCC and it isn't finding any issues.

-Wall it's not enough, but you can use -Wwrite-strings to catch this particular issue (see e.g. here).

Related