2

I am trying to reverse a C style string using the following simple program.

#include "stdio.h"
void reverse (char * str);
int main (int argc , char* argv[]){

    char *str = "hello";
    reverse(str);

return 0;

}

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

            }
            --end;
            while(str < end){
                    tmp = *str;
                    *str++ = *end;
                    *end-- = tmp;

            }
    }
}

I can't figure out why I get a "bus error" when I try to run the above program. I am using i686-apple-darwin10-gcc-4.2.1. Thanks

user7116
  • 63,008
  • 17
  • 141
  • 172
shiraz
  • 1,208
  • 2
  • 12
  • 26

2 Answers2

4

String literals in C are stored in the .data section of the binary which is read only memory. When saving it as const char * or char * they are non modifiable (in some cases if you modify the access fails silently or in your case you get a bus error because it's ROM).

Try using char str[] = "hello"; instead (I believe this should work, but I may be wrong).

Jesus Ramos
  • 22,940
  • 10
  • 58
  • 88
  • Nitpicker's corner: actually, the standard defines them as normal `char` arrays whose modification yields undefined behavior. The C++ standard is more sane and defines them as `const` `char` arrays, although they have an implicit conversion to `char *` for compatibility reasons. – Matteo Italia Jan 21 '12 at 00:02
  • string literals are not of type `const char *`, they are of type `array N` of `char` (and not `array N` of `const char`) ! They are just required to be non-modifiable. – ouah Jan 21 '12 at 00:03
  • @MatteoItalia Thanks I confused the C++ rules with C. – Jesus Ramos Jan 21 '12 at 00:07
  • Your naming is wrong. Although this is implementation-specific, traditionally `.data` is read/write. It's `.text` that's read-only. Modern implementations separate out `.rodata` from `.text` so the former can be non-executable, too. – R.. GitHub STOP HELPING ICE Jan 21 '12 at 01:29
  • @R.. I didn't think anyone would actually call me out on that. I guess my laziness caught up with me :P – Jesus Ramos Jan 21 '12 at 03:26
  • @JesusRamos , so modifying read only data leads to Bus error ? – Whoami Jan 21 '12 at 04:38
  • @Whoami It's actually undefined. On Linux systems I believe it fails silently, on BSD systems it causes a bus error or seg fault – Jesus Ramos Jan 21 '12 at 05:17
4

If you change char *str = "hello"; to char str[] = "hello"; your error will go away, since string literals are stored in a read-only part of memory and trying to modify "hello" may cause your program to crash (as it does in this case).

Declaring str as a char[] will copy the literal "hello" into a non-const buffer that you can modify the contents of.

AusCBloke
  • 18,014
  • 6
  • 40
  • 44