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?
Nayana Adassuriya
  • 23,596
  • 30
  • 104
  • 147

4 Answers4

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

Community
  • 1
  • 1
Alok Save
  • 202,538
  • 53
  • 430
  • 533
  • @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. – Alok Save Sep 18 '12 at 04:03
  • Adrian's comment came before the additional information and links were posted. – paddy Sep 18 '12 at 04:06
  • @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 – Adrian Cornish Sep 18 '12 at 04:06
  • @EdS. He had not at the time of my comment - this is the point race of stactoverflow :-) – Adrian Cornish Sep 18 '12 at 04:07
  • @Als what the hell does `It doesn't. It is users responsibility to ensure that.` mean? – Adrian Cornish Sep 18 '12 at 04:08
  • @AdrianCornish: Fair enough, can't see edits within the first five minutes – Ed S. Sep 18 '12 at 04:13
  • @AdrianCornish: I think it is pretty obvious OP asks 4 distinct Q's and my answer has 4 distinct numbers which represent answers to each.If you understand that,I don't see what you don't understand in the statement.If you still need any help understanding that, feel free to ask. – Alok Save Sep 18 '12 at 04:13
  • Two notes. Point 1: AFAIK the memory does not need to be readonly. But writing to it is undefined behavior. Point 3: AFAIK nothing in the standard ensures that the string stays in memory till the end of the program, as long as it stays in memory if there's a live pointer to **anywhere** within the string (including one byte past the terminating null character). – Analog File Sep 18 '12 at 04:16
  • @AnalogFile: Fair enough comment.I already have provided links to my previous answers which provide the standard quotes regarding the same. – Alok Save Sep 18 '12 at 04:18
  • @AnalogFile WTF are you talking about - live pointers - show me the C standard para for those - stays in memory - again show me the para - and of course it is read only OMG do you have a job? – Adrian Cornish Sep 18 '12 at 04:21
  • Actually, show me the para where it says it's read only instead of saying writing to it is undefined behavior. Because if it doesnt say, then it need not be. And AFAIK it does not say so. Also show me the para where it says it must stay in memory till the end of the program. As if it does not say so, then id does not need to be so. – Analog File Sep 18 '12 at 04:22
  • I asked first - show me anything in the C standard that mentions `stay in memory` – Adrian Cornish Sep 18 '12 at 04:24
  • AFAIK it is not in the standard. And that's exactly why AFAIK it does not need to stay in memory and the memory does not need to be readonly. A requirement is only such if it IS in the standard. I'm saying that AFAIK there is NO such requirement, that is is NOT in the standard. If you say it IS in the standard it's you that need to show me where. – Analog File Sep 18 '12 at 04:35
  • @AnalogFile Once you show me the standard def of `in memory` then I will answer – Adrian Cornish Sep 18 '12 at 04:44
  • rotfl. 1.7 describes the memory model. The standard itself sometimes uses the term 'in memory' without defining it (for example in 3.9.2/3). So I guess anything that is in a `memory location` as defined in 1.7 can be considered to be 'in memory'. – Analog File Sep 18 '12 at 04:55
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

Adrian Cornish
  • 23,227
  • 13
  • 61
  • 77
  • 2
    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*`. – Analog File Sep 18 '12 at 04:09
  • @AnalogFile A C++ compiler will flag this – Adrian Cornish Sep 18 '12 at 04:29
  • 1
    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). – Analog File Sep 18 '12 at 04:31
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
Chaitanya
  • 132
  • 2
  • 16
  • 1
    + you missed point 4 + it is bad practice to cast the result of malloc as you will inhibit possible runtime errors being thrown – Gewure Mar 08 '17 at 08:42
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 );
paddy
  • 60,864
  • 6
  • 61
  • 103
  • Really - what about p_two being bigger than p_one - use strncpy instead which is totally OT because the OP asked about C++ – Adrian Cornish Sep 18 '12 at 04:05
  • 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++. – paddy Sep 18 '12 at 04:13