if take array it will be fine but as i used *str1 and str2 it does not work
#include <stdio.h>
void copystr(char* ,char*);
int main()
{
char *str1="xxx";
char *str2= "yyy";
copystr(str1, str2);
printf("\n %s",str2);
}
void copystr(char *dest,char *src)
{
while(*src!='\0')
*dest++=*src++;
*dest='\0';
return;
}
char *str = "some string"
Here str is a pointer pointing to a constant memory, which can't be edited and leads to undefined behaviour.
But If you declare like
char str2[] = "some string"
Now str2 above is pointing to a memory which is not constant and can be changed. Thus will work.
More explanation here:
char *array and char array[]
Destination string str1 is a string literal. String literals are non modifiable. Any attempt to modify it will invoke undefined behavior.
Related
I am trying to perform swap operation as shown in below program, but it seems to crash when I am copying the element b into a (line 3 in swap() method) - this happens if the input is a char string i.e, char *str; If it is a character array instead (as in char str[];) the swap operation works fine.
#include<stdio.h>
void swap(char *a, char *b)
{
char tmp;
tmp = *a;
*a = *b; /* crash occurs here */
*b = tmp;
}
void func(char *a)
{
swap(a+1, a+2);
}
int main()
{
char *str = "abc";
// char str[] = "abc"; /* with this char array, the above swap func works */
func(str);
}
I think this is related to some C string rules that I seem to be unaware of. Please help!
String literals are read-only, trying to modify a string literal leads to undefined behavior.
Simplest solution? Declare it as an array instead:
char str[] = "abc";
char *str = "abc";
Above puts the string in the constant data section (also known as .rdata) of the program.As this is treated as constant data, it can not be modified
char str[] = "abc";
Above puts the string in the stack area of the program, as declared inside the function scope.This data can be modified.
As this is about the storage of string data, you are getting Crash in first declaration.
'char *str = "abc";'
The above places the abc in read only memory. So it cannot be modified.
'char str[]="abc";' is placed in stack. so it can be modified.
I was working on the "c programming language" exercise2.4, which deletes each character in s1 that matches any character in the string s2.Below is my code, it works. However,if I change the definition in Main function from char c1[ ]="abcde" to char *c1="abcde", it will turns out segmentation fault(core dumped). Any idea why?
#include<stdio.h>
#define UNREPEAT 1
#define REPEAT 0
void squeeze(char *s1,char *s2);
void main(){
char c1[]="abcde";
char c2[]="cd";
printf("c1 is %s\n",c1);
squeeze(c1,c2);
printf("the final result is %s\n",c1);
}
void squeeze(char *s1,char *s2){
int i,j,judge;
int k=0;
for(i=0;*(s1+i)!='\0';i++){
judge=UNREPEAT;
for(j=0;*(s2+j)!='\0';j++){
if (*(s1+i)==*(s2+j)){
judge=REPEAT;
break;}
}
if( judge==UNREPEAT){
* (s1+k)=*(s1+i);
k++;}
}
*(s1+k)='\0';
}
Because
char c1[] = "abcde";
declares an array, it's readable and writable and will always have 6 bytes (if you consider the terminating '\0') you can't extend it but of course you can use it to store less bytes.
While
char *c1 = "abcde";
is a static string literal it shall not be modified, you should always declare string literals using the const qualifier, that way the compiler would warn you if you try to modify its contents, which is illegal, just use
const char *c1 = "abcde";
char *c1="abcde"
This is a string literal which is read-only and in your function you try to change the contents of it so you might hit seg fault.
Whereas the other case
char c1[] = "abcde";
You are allocating memory on the stack whose contents can be modified.
PS: String literals are read-only
In the code below the result is stack overflow. Though null character is there with both the strings, so the strcpy loop should terminate as the source string has null character. Why stack overflow occurs??
#include <stdio.h>
#include<strings.h>
int main(void) {
char *str="Hello world";
char *str1="Good morning";
strcpy(str,str1);
printf("%s",str);
return 0;
}
The error isn't stack overflow, but modifying a string literal.
str is a pointer that points to a string literal "Hello world", and modifying a string literal is undefined behavior.
Change str to:
char str[100] = "Hello world";
I've verified in GDB that the program crashes on the *(a) = *(b) line. This does not make sense to me.
In my main function I allocated a 5 bytes for the char* string. I pass two pointers to swap, one is string offset by sizeof(char) and the other is the pointer to string. These pointers are copied to swap()'s call stack. The 5 bytes I allocated earlier should still be on the stack so swap() should have no problem with dereferencing and writing to those locations on stack, right?
int main(int argc, char* argv[])
{
char *string = "abcd";
swap((string+1), string);
printf("%s\n",string);
return 0;
}
void swap(char *a, char *b)
{
if(!a || !b)
return;
char temp = *(a);
*(a) = *(b);
*(b) = temp;
}
char *string = "abcd";
is a pointer to a string literal and string literals are immutable in C. Modifying a string literal invokes undefined behavior.
Change the declaration of string to:
char string[] = "abcd";
to fix you program. Here string is an array, initialized with the content of a string literal and is modifiable.
String literals like "abcd" are read only, you must not change them. Use
char string[] = "abcd";
instead.
you should use char string[] = "abcd";, becase string is inmuttable in char* string= "abcd";
Why this code does not work?
int main(){
char *str ="abcde";
scanf("%s",str);
printf("%s",str);
}
but this works?
int main(){
char str[] ="abcde";
scanf("%s",str);
printf("%s",str);
}`
In the first code, you declare a pointer, which points to a string literal: "abcde".
This might be a constant, and you will not be able to change it.
The second code is declaring an array and filling it with ['a','b',c','d','e','\0'], and is not a constant - so you can change it.
Because char *str ="abcde"; is a pointer to string literal which is most likely stored in read-only memory.
char str[] ="abcde"; is an array initialized with "abcde".
You should also check out Difference between char* and char[]
When string value is directly assigned to a pointer, it’s stored in a
read only block(generally in data segment) that is shared among
functions
char *str = "GfG";
...
char str[] = "GfG"; /* Stored in stack segment like other auto
variables */ *(str+1) = 'n'; /* No problem: String is now GnG */
http://www.geeksforgeeks.org/archives/5328