Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding char *, char[] and strcpy()

My understanding is as follows:

  • char * points to a string constant, modifying the data it points to is undefined. You can, however, change where it points to.

  • char[] refers to a block of memory that you can change. You can change its contents but not what it refers to.

  • strcpy(dest, src) copies src into dest.

My question is, is it incorrect to use strcpy() with the dest being a char * that is already pointing to something (as I believe the old contents will be overwritten by strcpy() - which is undefined behaviour)?

For example:

char *dest = malloc(5);
dest = "FIVE";

char *src = malloc(5);
src = "NEW!";

strcpy(dest, src); /* Invalid because chars at dest are getting overwritten? */
like image 704
CS Student Avatar asked Aug 26 '14 09:08

CS Student


People also ask

Does strcpy work on char?

char* strcpy(char* destination, const char* source); The strcpy() function copies the string pointed by source (including the null character) to the destination. The strcpy() function also returns the copied string.

What is the difference between char * and char array?

The main difference between them is that the first is an array and the other one is a pointer. The array owns its contents, which happen to be a copy of "Test" , while the pointer simply refers to the contents of the string (which in this case is immutable). Save this answer.

What is strcpy?

strcpy() — Copy Strings The strcpy() function copies string2, including the ending null character, to the location that is specified by string1. The strcpy() function operates on null-ended strings. The string arguments to the function should contain a null character (\0) that marks the end of the string.

What does char [] do in C?

In C programming, a string is a sequence of characters terminated with a null character \0 . For example: char c[] = "c string"; When the compiler encounters a sequence of characters enclosed in the double quotation marks, it appends a null character \0 at the end by default.


1 Answers

Your understanding is not totally correct, unfortunately.

char * points at character data, and since there's no const in there, you can write to the data being pointed to.

However, it's perfectly possible to do this:

char *a = "hello";

which gives you a read/write pointer to read-only data, since string literals are stored in read-only memory, but not "considered" constant by the language's syntax.

It's better to write the above as:

const char *a = "hello";

To make it more clear that you cannot modify the data pointed at by a.

Also, your examples mixing malloc() and assignment are wrong.

This:

char *dest = malloc(5);
dest = "FIVE"; /* BAD CODE */

Is bad code, and you should never do that. It simply overwrites the pointer returned by dest with a pointer to the string "FIVE" which exists somewhere in (again, read-only) memory as a string literal.

The proper way to initalize newly allocated memory with string data is to use strcpy():

char *dest = malloc(5);
if(dest != NULL)
  strcpy(dest, "five");

Note that checking the return value of malloc() is a good idea.

There's no problem doing multiple writes to the same memory, that's a very basic idea in C; variables represent memory, and can be given different values at different times by being "written over".

Something as simple as:

int a = 2;

printf("a=%d\n", a);
a = 4;
printf("a=%d\n", a);

demonstrates this, and it works just fine for strings too of course since they are just blocks of memory.

You can extend the above malloc()-based example:

char *dest = malloc(5);
if(dest != NULL)
{
  strcpy(dest, "five");
  printf("dest='%s'\n", dest);
  strcpy(dest, "four");
  printf("dest='%s'\n", dest);
  strcpy(dest, "one");
  printf("dest='%s'\n", dest);
}

and it will print:

dest='five'
dest='four'
dest='one'
like image 102
unwind Avatar answered Sep 30 '22 04:09

unwind