简体   繁体   中英

C string function (strcopy,strcat…,strstr) with arrays and pointers

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:

  1. The stack, where variables you declare in a function are allocated
  2. The heap, where calls to malloc/calloc/realloc allocate memory
  3. Global static storage, where non-const global variables (those declared outside of a function) are allocated.
  4. Global constant storage, where all string literals and other global variables declared 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM