Trouble-shooting

I am trying to change the line.

This is the code I tried:

#include<stdio.h> #include<string.h> int main(){ char *c="I am a good boy"; printf("\n The input string is : %s\n",c); printf("\n The length of the string is : %d\n",strlen(c)); int i,j; char temp; int len=strlen(c); for(i=0,j=len-1;i<=j;i++,j--) { temp=c[i]; c[i]=c[j]; c[j]=temp; //printf("%c\t%c\n",*(c+i),*(c+(len-i-1))); } printf("\n reversed string is : %s\n\n",c); } 

The code outputs a Bus error : 10 .

But if I rewrote the same code as:

 int main(void) { char *str; str="I am a good boy"; int i,j; char temp; int len=strlen(str); char *ptr=NULL; ptr=malloc(sizeof(char)*(len)); ptr=strcpy(ptr,str); for (i=0, j=len-1; i<=j; i++, j--) { temp=ptr[i]; ptr[i]=ptr[j]; ptr[j]=temp; } printf("The reverse of the string is : %s\n",ptr); } 

It works great.

Why does the first code throw a bus error or a segmentation error?

+8
c string string-literals
source share
5 answers

A bus error occurs because in many (if not most or all modern) C compilers, string literals are allocated in read-only memory.

You change the string into place. In the first piece of code that you are trying to write to a string literal. Not a good idea.

In the second case, you malloc'd a string that puts it in a heap. It is now safe to cancel this line in place.

ADDITION

To a commenter who asked about segfaults and bus errors, this is a great question. I have seen both. Here is the bus error on mac:

 $ cat bus.c char* s = "abc"; int main() {s[0]='d'; return 0;} $ gcc --version bus.c && ./a.out i686-apple-darwin10-gcc-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5659) Copyright (C) 2007 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Bus error 

On other operating systems / compilers you can get segfault.

+16
source share

Copying it into a bunch is one option. However, if you just want to allocate a local (stack) array, you can do:

 char str[] = "I am a good boy"; 

Then the constant string will be copied onto the stack.

+6
source share

The character arrays specified in the form "I am a good boy" are usually constant - you cannot change them. That is why your first option will work. The second does not, because you create a copy of the data and then modify it.

+1
source share

char * str = "I am a good boy"; Processed as a literal and attempting to modify it will result in a bus error. This is equivalent to const char * str = "I'm a good boy", i.e. A pointer to a constant string and an attempt to change a constant string are not allowed.

EDIT: The moment you malloc () and copy you are playing with a copy of the original string, and ptr is not of type 'const char *', instead it is 'char * ptr' and do not complain.

0
source share

Compiling with C ++ (g ++) shows the deprecated string literal assignment for non-const char *, which is intended to prevent this error:

 ed@bad-horse:~/udlit_debug$ g++ ../buserr.cpp ../buserr.cpp: In function 'int main()': ../buserr.cpp:5:13: warning: deprecated conversion from string constant to 'char*' ../buserr.cpp:7:61: warning: format '%d' expects type 'int', but argument 2 has type 'size_t' 

The corresponding warning is on line 5.

Changing the declaration to const char *, as indicated, prevents assignment to a literal string.

This is also a lesson on why you should not ignore warnings.

0
source share

All Articles