Whenever I am using one of these functions in dev-C++(I know its old but for some reason still taught at my college.)
strcat,strcpy,strcmp,strchr...//And their variants stricmp...
The first argument for these functions always has to be an array (ie:
char ch[]="hello";
But it can't be a pointer to a string bc for some reason this causes a crash. In fact for an example look at both of these codes:
code1:
#include<stdio.h>
#include<string.h>
main()
{char ch[20]="Hello world!";
char *ch2="Hello Galaxy!";
strcat(ch,ch2);
printf("%s",ch);
scanf("%d")//Just to see the output.
}
This code works fine and gives the expected result(Hello World!Hello Galaxy!)
But the inverse code2 crashes.
code2:
#include<stdio.h>
#include<string.h>
main()
{char ch[20]="Hello world!";
char *ch2="Hello Galaxy!";
strcat(ch2,ch);
printf("%s",ch2);
scanf("%d")//Just to see the output.
}
This code crashes and causes a
file.exe has stopped working Error.
This is the same for almost all of the strings functions that takes two arguments. What is the cause of this problem.
With char *ch2 = "Hello Galaxy!";
you are obtaining a pointer to a string literal. You should never attempt to modify a string literals, as this invokes undefined behaviour (which in your case has manifested as a crash).
With char ch[20] = "Hello World!";
you are initialising an array using the contents of a string literal, so you end up with your own modifiable copy of the string in ch
.
Also, note that 20 characters is not enough for Hello World!Hello Galaxy!
to fit, and this is also undefined behaviour, and known as overflowing your buffer.
char ch[20] = "Hello world!"
ch
is an array of char
initialized by the elements of a string literal (and the rest of the array is initialized with 0
).
char *ch2="Hello Galaxy!";
ch2
is a pointer to a string literal.
String literals are not required to be modifiable in C. Modifying a string literal is undefined behavior in C.
There are two problems. The first is that your string literal is not long enough to hold the concatenated string "Hello world!Hello Galaxy!"
. The space allocated is only 13 bytes (12 characters plus the space for the '0' byte that terminates the string). The concatenated string requires 26 bytes (25 chars + 1 null-valued char).
However, this isn't the real problem. The real problem is that you're accessing memory that you should not be, and that the operating system often protects. Most implementations of C provide four areas of storage:
const
are allocated. The first three areas are, in principle, modifiable. The fourth area is not, and is often stored in memory that the operating system marks as read-only. When you assign the string literal "Hello Galaxy!" to
"Hello Galaxy!" to
char* ch2 , the variable
ch2` points into global constant storage.
To give you a better idea, the following code generals a segfault when I run it:
#include <stdio.h>
int main(int argc, char** argv)
{
char* s = "Foo bar baz";
s[0] = 'B';
printf("%s\n",s);
return 0;
}
The segfault occurs in the s[0] = ...
line, because I'm accessing storage that the operating system has marked as read-only.
That is about the size of pointer array..overflow problem.. char *ch2="Hello Galaxy!";
when you use this automaticly the size of *ch2 gets 14 with the null character but when you move the ch[]
array into the *ch2
, you get an error. you cannot move an array with 20 size into another array with 14 size...
String literals are read-only.This means that if you assign:
char* str="Hello";
You can't pass str as first argument of strcpy and strcat, because this would cause to write over read-only memory. If instead you declare it this way:
char str2[]="Hello";
Then the str2 array is stored on the stack, and you can change it's values.
You can still pass str to functions like strcmp (which just reads the wto strings and compare them), or as second argument of strcat and strcpy, since this doesn't cause the string to be written.
you got an error because you try to access the code section of your process which is read-only. that is your string literal present in code and the address of that string literal you use in assignment to your pointer variable. So you can access the code but you cannot modify this.
every executable file contain some sections like...
1.text(code of your program as well as string literals present here)
2.data uninitialized
3.data initialized
you can veryfy this by command
size <executable-file-neme>
Also using command
objdump -D <executable-file-neme>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.