Understanding char *, char [] and strcpy ()

My understanding is this:

  • char *

    points to a string constant, changing the data it points to is undefined. However, you can change what it points to.

  • char[]

    refers to a block of memory that you can change its contents, but not what it refers to.

  • strcpy(dest, src)

    copies src

    to dest

    .

My question is, is it wrong to use strcpy()

when dest

is char *

, which already points to something (since I believe old content will be overwritten strcpy()

- this is undefined behavior)?

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? */

      

+3


source to share


4 answers


Unfortunately, your understanding is not entirely correct.

char *

points to character data, and since there isn't const

, you can write to the data it points to.

However, this is quite possible:

char *a = "hello";

      

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

Better to write above:

const char *a = "hello";

      

To make it clearer, you cannot change the data it points to a

.

Also, your mix malloc()

and assignment examples are wrong.

It:

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

      

Bad code and you should never do that. It just overwrites the pointer returned by a dest

pointer to a string "FIVE"

that exists somewhere (again, read-only) as a string literal.



The correct way to initialize 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 malloc()

is a good idea.

There is no problem doing multiple writes to the same memory, which is a very simple idea in C; variables are memory and can be assigned different values ​​at different times, being "overwritten".

Something simple:

int a = 2;

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

      

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

You can expand on the above example malloc()

:

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'

      

+10


source


My understanding is this:

  • char *

    points to a string constant, changing the data it points to is undefined. However, you can change what it points to.

Here you are referring to an expression like

char * string = "mystring";

      

You are correct that the execution string[1]='r';

is undefined. But this is not because of char *

, but because of the string literal associated with the fact that it is placed in permanent memory.

Compare this with

char string[] = "mystring";

      

where I define an array in RAM where the specified string fits. It is allowed to do here string[1] = 'r';

because we are in normal data memory.

This looks like your guess, but take this:

char string[] = "mystring";
char * string2 = string;

      

string2[1] = 'r';

Valid here as it points to a place where the entry is also good.

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

      

Yes, because the name there is just a variable name, not a pointer.



strcpy(dest, src) copies src into dest.

      

Right.

My question is, is it wrong to use strcpy () when dest is a char * that already points to something (as I believe the content will be overwritten by strcpy () - which is undefined behavior)?

It depends on what you mean by "already pointing to something" ...

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? * /

Here you are mixing a few things again.

First, you have it dest

pointed to a new block of memory. After that, you point to the place where you cannot write and the chunk of memory is lost (memory leak).

The same thing happens with src

.

So, it strcpy()

fails.

You can do

char *dest = malloc(5);

char *src = "NEW!";

strcpy(dest, src);

      

as here dest

indicates the place to be written, but src

indicates the payload.

+3


source


Quick analysis:

char *dest = malloc(5);
// 'dest' is set to point to a piece of allocated memory
// (typically located in the heap)
dest = "FIVE";
// 'dest' is set to point to a constant string
// (typically located in the code-section or in the data-section)

      

You are assigning to the variable dest

twice, so obviously the first assignment doesn't matter.

I like to write:

int i = 5;
i = 6;

      

In addition, you "lose" the address of the allocated memory, so you cannot release it later.

+2


source


char * is a pointer to a memory address, so you can change the information contained in that address.

The difference between char * and char [] is that char [] is not dynamic, you cannot resize it. Also, char * points to a heap address, while char [] is stored on the stack of your program.

You can use strcpy with both pointers and arrays and it will work as data from both can be overwritten.

+1


source







All Articles