memory allocations

in this code have we allocated any memory for string?
how does the pointer remember the complete string?
1
2
3
4
5
6
7
8
9
10
11
12
13
  include <iostream>

using namespace std;

int main()
{
int i;
char *a;
a="abc";
for(i=0;i<4;i++)
cout<<a[i];
    return 0;
}
in this code have we allocated any memory for string?

"abc" is a string literal. The compiler will allocate space for it. a is then set to be equal to the address of the memory that's allocated for "abc".

Edit: According to http://en.cppreference.com/w/cpp/language/string_literal the above is not true for C++11. It is true for C++03, but is deprecated in that standard:

In C, string literals are of type char[], and can be assigned directly to a (non-const) char*. C++03 allowed it as well (but deprecated it, as literals are const in C++). C++11 no longer allows such assignments without a cast.
Last edited on
Disch made a good post here explaining strings
http://www.cplusplus.com/forum/beginner/108879/

The only thing I would like to add to what Disch said in his example is that ptr == buffer after char* ptr = &buffer[0]; In other words, your code could say const char* a = "abc"; or char a[] = "abc"; The syntax is pretty much interchangeable between arrays and pointers

See Disch's post below.
Last edited on
does compiler free the memory of that string ("abc") after completing the execution ?
Yes.

However if you are suppose to be using "dynamic" memory allocation, your program does not do that yet.
Last edited on
string literals are allocated statically, that means, they are part of the executable.
when the program terminates it is taken out of the memory, so all statically allocated storage is removed with it.

under windows, the operating system also removes all other storage after the program is executed, even if the programmer forgot to delete dynamic storage.
does compiler free the memory of that string ("abc") after completing the execution ?

Can you be less vague, please? "After completing the execution" of what, exactly? The whole program? The code block in which the literal is used? Something else?

I'm not an expert on string literals, but according to
http://en.cppreference.com/w/cpp/language/string_literal :

String literals have static storage duration, and thus exist in memory for the life of the program.

It also says:

In C, string literals are of type char[], and can be assigned directly to a (non-const) char*. C++03 allowed it as well (but deprecated it, as literals are const in C++). C++11 no longer allows such assignments without a cast.

so my comments in my previous post may or may not be true, depending on which version of C++ you're using. I've edited that post.
Last edited on
kevinkjt2000 wrote:
The only thing I would like to add to what Disch said in his example is that ptr == buffer after char* ptr = &buffer[0]; In other words, your code could say char* a = "abc"; or char a[] = "abc"; The syntax is pretty much interchangeable between arrays and pointers



Actually... they're not quite interchangeable. Remember that in char* a = "abc" (if that even compiles... which in a standard compliant compiler it wouldn't, because "abc" is a literal and is therefore const --- but MikeyBoy already mentioned this), 'a' is a pointer. Therefore the actual string data exists elsewhere.

On the other hand, with char a[] = "abc"... 'a' is an array, and therefore actually has allocated space for the string. The data exists right in the 'a' array.... 'a' is not simply pointing to data that exists elsewhere.. it actually HAS the data.
It does compile in gcc 4.8.1 http://ideone.com/ZSFKWW
C++11 seems to allow it too http://ideone.com/sYEEa0

char a[] = "abc" In this example a points to the allocated space of {'a', 'b', 'c', '\0'} and then the operator [] indexes to the right location in the array. Basically the difference is that char a[] makes a a const char* whereas char* a only lacks the constant.

char* a = "abc" This example also allocates space and then assigns a to point to it, with the only difference being the missing const. Even if the literal is const it can still be assigned to a non const pointer that points to the same spot.

I edited my previous post to include const.


See Disch's post below
Last edited on
char a[] = "abc" In this example a points to the allocated space of {'a', 'b', 'c', '\0'}


Actually.... in that example a is an array, not a pointer, therefore it doesn't point to anything.

Basically the difference is that char a[] makes a a const char* whereas char* a only lacks the constant.


No, the difference is that one is an array and therefore actually has the storage of the data, whereas the other is a pointer which refers to data stored elsewhere.

C++11 seems to allow it too http://ideone.com/sYEEa0


No.... whatever compiler ideone is using seems to allow it. The C++11 standard does not.


EDIT:

It may seem like I'm splitting hairs here.. but when dealing with pointers, where and how the data is stored is everything... so this is actually kind of a big deal.

Here's an example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
char ar[] = "example";
char* ptr1 = "example";  // assuming this compiles
char* ptr2 = "example";  // assuming this compiles

// here... 'ar' contains the "example" string.
// but ptr1 and ptr2 simply point to string data elsewhere in memory

cout << ar; // prints "example" as expected
cout << ptr1;  // ditto
cout << ptr2;  // ditto


// Since 'ar' has its own storage, we can modify it at will

strcpy(ar, "butt");
cout << ar; // prints "butt" as expected
cout << ptr1; // prints "example", as ptr1 still points to other string data
cout << ptr2; // ditto

// Here's where it gets tricky...

strcpy(ptr1, "foo");  // this is syntactically legal because ptr1 is a modifiable ptr,
  // however this MIGHT CRASH because it might be pointing to string data in
  // read only memory.  This is why these kinds of pointers should always be
  // const char*s and not char*s

  // but assuming that doesn't crash... and even assuming it does what we'd
  //  expect...

cout << ptr1;  // hopefully prints "foo"
cout << ptr2;  // ?? does it print "example" or does it print "foo"?

  // The answer to this is not obvious, because ptr1 and ptr2 may have been
  // pointing to the same string data.  If we were able to modify that string data
  // through the above strcpy... then printing ptr2 will also show "foo".
  // However if ptr1 and ptr2 pointed to different string data, then this will
  // still print "example".
  //
  // It depends on (among other things) whether or not the compiler/optimizer
  // pooled the string data.
  //
  // However... regardless of all that mess...

cout << ar;  // this still prints "butt" because it has its own storage
    // and therefore does not care about any of that other crap 
Last edited on
Both the compilers are gcc-4.8.1
I did not think about the read only memory being a problem, and turns out most compilers do use read only memory for this situation. So that code does cause a segfault on line 22. Great example!
Topic archived. No new replies allowed.