0
char * p_one = "this is  my first char pointer";
char * p_two= "this is second";
strcpy(p_one ,p_two);

consider the above code. This is giving access violation error. So please help to understand

  1. where is the current "this is my first char pointer" string stored in memory? heap or stack
  2. why I need to allocate memory for p_one before call strcpy, even it's already storing the first string. why "this is second" string cannot copy to same location?
  3. If I allocate memory for p_one before call strcpy then what happen to "this is my first char pointer" string that was pointed by p_one ? is it keep in memory?
  4. How strcpy knows specific pointer have allocated memory or not?
1
  • Oh point 4 last thing - strcpy assumes you own and know the destination - otherwise all bets are off Commented Sep 18, 2012 at 4:23

4 Answers 4

7
  1. Implementation defined(usually read only) memory.[Ref 1]
  2. You do not need to as long as you don't modify the source string literal.
  3. If you allocate memory to p_one, then it will point to the newly allocated memory region, the string literal may/may not stay in the memory, but it is guaranteed to be alive throughout the lifetime of the program.String literals have static duration lifetime.[Ref 2]
  4. It doesn't. It is users responsibility to ensure that.

Good Read:
[Ref 1] What is the difference between char a[] = ?string?; and char *p = ?string?;?
[Ref 2] "life-time" of string literal in C

Sign up to request clarification or add additional context in comments.

15 Comments

@AdrianCornish: There is nothing more to explain than what my this answer and what my previously linked answers explain.I suspect your downvote stems more from a self answer promotion perspective than any real meaning.
Adrian's comment came before the additional information and links were posted.
@Als Saying things like 'you are wrong' does not help the OP when I posted the comment your answer was very sparse with no reason given
@EdS. He had not at the time of my comment - this is the point race of stactoverflow :-)
@Als what the hell does It doesn't. It is users responsibility to ensure that. mean?
|
1

First off your compiler should be warning that the p_one and p_two are actually const char * because the compiler allocates the storage of this string at compile time.

The reason you cannot modify them is because in theory you could overwrite memory after them, this is what causes hack attack with a stackoverflow.

Also the compiler could be smart and realize that you you use this string in 10 places but notices it is the same, so modifying from one place changes it - but that destroys the logic of the other 9 places that uses it

3 Comments

Actually the compiler shall not flag this. In C string literals are of type char* but writing to them is undefined behavior. In C++ they are of type const char[n] for a suitable value of n, but the language have a special rule that says that they, unlike identical user defined types, convert to an rvalue of type char*.
@AnalogFile A C++ compiler will flag this
Yup, I was just checking. Recent standards deprecate (but still allow) assignment of a string literal to a char*. Therefore a modern C++ compiler should flag it with a warning (not so a C compiler).
1

Answering all the questions in order

  1. It's bit straight forward that your char pointer is always stored in stack. Remember even though you are using Memory allocation, it is only for determining the length of the string and appending the '\0' character.

This would be one solution, according to code you have mentioned:

int main()
{
   char * p_one = "this is  my first char pointer";
   char * p_two= "this is second";
   size_t keylen=strlen(p_two);
   p_one=(char *)malloc(keylen*sizeof(char));
   strncpy(p_one ,p_two,strlen(p_one));
   printf("%s",p_one);

   return 0;
}
  1. When you have declared a char pointer it only points to the memory allocation. So string copy doesn't point to the end of character. Hence it is always better to use strncpy, in this conditions.

  2. Yes it is allocating memory.

  3. it is bad practice to cast the result of malloc as you will inhibit possible runtime errors being thrown, thanks Gewure

1 Comment

+ you missed point 4 + it is bad practice to cast the result of malloc as you will inhibit possible runtime errors being thrown
0

When you have a string literal in your code like that, you need to think of it as a temporary constant value. Sure, you assigned it to a char*, but that does not mean you are allowed to modify it. Nothing in the C specification says this is legal.

On the other hand, this is okay:

const size_t MAX_STR = 50;
char p_one[MAX_STR] = "this is  my first char pointer";
const char *p_two = "this is second";
strcpy( p_one, p_two );

2 Comments

Really - what about p_two being bigger than p_one - use strncpy instead which is totally OT because the OP asked about C++
That was not the case. The OP was clearly expecting to be copying into a buffer that had enough storage. In my example, p_two can be up up to MAX_STR-1 characters long. It's quite reasonable to actually specify a buffer size when you intend to modify. Good point about strncpy, but with the caveat that quite often you know that your buffer is large enough and you don't bother to use it. I don't consider the question off-topic... The C string functions are also part of C++.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.