tags:

views:

468

answers:

1

I call the function provided by Chris Conway (http://stackoverflow.com/questions/198199/how-do-you-reverse-a-string-in-place-in-c-or-c) from main (C code). When I run this program using cygwin, program crashes when it is in while loop (commented the lines where it breaks). Could you please explain what is going wrong here. Thanks

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

void strrev(char* z);

int main()
{
        char *a;
    printf("before reverse: %s\n", a);
        strrev(a); // function provided by Chris Conway
    printf("after reverse: %s\n", a);
    return 0;
}

void strrev(char *str) {
  char temp, *end_ptr;

  /* If str is NULL or empty, do nothing */
  if( str == NULL || !(*str) )
    return;

  end_ptr = str + strlen(str) - 1;

  /* Swap the chars */
  while( end_ptr > str ) {
    temp = *str;
    *str = *end_ptr;  //crashes here (cygwin gives segmentation fault)
    *end_ptr = temp;  //for testing, if I comment out line above, it crashes here
    str++;
    end_ptr--;
  }
}
+8  A: 

The function is fine, but your main() does not appear to initialize the string a.

Try:

int main() {
  char a[1024];
  strcpy(a, "Some string");
  printf("before reverse: %s\n", a);
  strrev(a); // function provided by Chris Conway
  printf("after reverse: %s\n", a);
  return 0;
}

Note that I create a copy of "Some string" inside a (instead of directly assigning char* a = "Some String") because trying to alter a constant string directly will not compile. And if you did manage to compile (e.g. lax compiler, or you forced the constness away via cast/const_cast) then you run a very high risk of crashing your program, because "Some string" is actually in a portion of memory that is read-only on some systems, which is why a copy must be made inside a local variable (i.e. on the stack) or a new variable (allocated with new or malloc, i.e. on the heap.)

vladr
Or he can do: const char *a = "Some string";
strager
No, if he/she did that than strrev will attempt to modify a const, which should not compile. Moreover, since the const is actually coming from the executable image itself, even if the program were forced to compile, a crash may ensue (trying to alter memory mapped to the exec. image.)
vladr
Thanks Vlad. Actually I used: char *a = "Some string"; strrev(a). In this case it compiles but crashes. Does the above initialization also makes the 'a' - pointer to const ? And is that the reason, it crashed ?
Got it. Just saw your edited comments. thanks
Ah, my bad ... Forgot about that little detail. Silly me. Regardless, the compiler /should/ have warned him about using a non-const char * to store a string literal...
strager
well then, you can do char a[] = "Some string"; instead :)
Johannes Schaub - litb
@strager, note that in C, unlike in C++, string literals are of type char[N] (not of type char const[N]), so the compiler could, but not must, warn. (well, for C++ neither, but there's more reason there, because of the const)
Johannes Schaub - litb
I feel like you just answered someone's homework question? :/
ray