-1

I know this question has been asked many times but I am completely stuck.

EDIT: This question is different from previous questions because the problem was not with the code for the reverse function, but rather what types of values can be passed to the reverse function (ie. array vs pointer) .. see answers below for more info.

I am simply trying to reverse a c style string. I have taken copied and pasted the code to do so directly from Cracking the Coding Interview. (see below)

void reverse(char *str) {
    char * end = str;
    char tmp;
    if (str) {
        while (*end) {
            ++end;
        }
        --end;
        while (str < end) {
            tmp = *str;
            *str++ = *end;
            *end-- = tmp;
        }
    }
}

This does not work for me. I am very new to C so perhaps I am compiling the code wrong. My main function looks like:

int main(int argc, char *argv[])
{   
    char *string = "foobar";
    reverse(string);
    printf("%s\n", string);

    return 0;
}

I am using Cygwin with Windows 8.1 and on the command line I am running:

gcc ex1.c -Wall -o exe1
./exe1

Everytime I get a pop up from windows saying "exe1.exe has stopped working". I tried putting a print statement in the while loop to try debug and see what is going on. It reaches the while loop once before the windows pop up appears.

EDIT: After reading the comments I have also tried changing the code in main to :

char string[] = "foobar"; 
reverse(string);

When I do this my program just hangs.

What am I doing wrong?

Thanks!

user1795370
  • 332
  • 2
  • 4
  • 18
  • 4
    You are passing a constant string into the `reverse` function which then trys to modify it. That's not valid as constant strings are readonly. – kaylum Apr 20 '15 at 06:46
  • 3
    just change `char *string = "foobar";` to `char string[] = "foobar";` – Dabo Apr 20 '15 at 06:48
  • 1
    This is basically 'just another string reversal' question (hence the question I chose to close it as a duplicate of). It could also be 'just another "do not modify string literals"' question too. Either way, it is not really a novel question. – Jonathan Leffler Apr 20 '15 at 06:58
  • I am aware that it is not novel. I stated that in the beginning. Regardless, none of the other answers helped me figure it out. It seems that the question is being asked a lot because there is a lot going on (especially for new coders, who may not be sure how to read code and ask questions yet), and not because people aren't trying to find the answer. – user1795370 Apr 20 '15 at 16:46

2 Answers2

4

The problem with your code is pertaining to this part char *string = "foobar"; Here "foobar" is stored in a memory location and string holds the first location of "foobar" so basically now string behaves as a const so you cannot change its contents.

You could do this instead char string[] = "foobar";.

EDIT: as @jonathan-leffler mentioned, I forgot to mention the memory locations.

char *string = "foobar";
Is stored on the Data Segment which is given memory during compile time and attempts to modify this during runtime will give you a Seg Fault.

whereas,
char string[] = "foobar";
Is stored on the stack and can be modified.

EDIT2: Read the comments below @jonathan-leffler has more to add

Karthik Nayak
  • 731
  • 3
  • 14
  • Welcome to Stack Overflow. Both character arrays and string literals are stored in (a sequence of) memory locations. The difference is that it is not legitimate to modify a string literal — it leads to undefined behaviour, which is something to avoid at all costs. On many (but not all) systems, a string literal is stored in readonly memory and an attempt to modify it will cause the program to crash — as in the question. – Jonathan Leffler Apr 20 '15 at 07:04
  • 1
    Hmmm; somewhat better, but… The data segment is writable, and string literals are normally stored in the text segment (which is not writable) rather than the data segment, at least with modern C compilers. If you are working with ancient compilers (meaning compilers released in the last millennium rather than this one; an over-simplification, but approximately accurate), then you might find that string literals are stored in the data segment and can be modified, but it is still undefined behaviour to modify them. – Jonathan Leffler Apr 20 '15 at 07:15
  • 2
    @KarthikNayak [this](http://stackoverflow.com/questions/2589949/c-string-literals-where-do-they-go) might be interesting for you – Dabo Apr 20 '15 at 07:24
  • So it took me a while but I finally tried this. My program still hangs. Any idea why? I am now passing `char string[] = "foobar"; reverse(string);` – user1795370 Apr 23 '15 at 04:56
  • @user1795370 Can you edit your question and show the changes you've made? – Karthik Nayak Apr 23 '15 at 10:13
1
 char *string = "foobar";

here string is pointer to a sequence of characters.You cannot modify the value foobar using string.For example try this

 string[1]='p';//will throw error

and in your reverse() you are exactly doing this.Use this instead

char string[]="foobar"; //and now you can modify it

string[1]='p';//wiil work

So reverse() will also work.

Gaurav Sehgal
  • 7,422
  • 2
  • 18
  • 34
  • This doesn't really emphasize the crucial point, namely that string literals cannot be modified. If you have `char data[] = "foobar";` and `char *string = data;`, you have `string` as a 'pointer to a sequence of characters', but the sequence is modifiable, whereas when `string` points at `"foobar"`, the sequence is not modifiable. – Jonathan Leffler Apr 20 '15 at 07:09