From: AY on
Hi There,

This is only for my understanding... I know most of the code in here
is wrong. But I was trying out something and am trying to make some
sense out of it.. the code is as follows:

int main( void )
{

const char* ptrCh = new char[50];
ptrCh = "ABCDE";
cout<<" ptrCh = " <<ptrCh<<endl;

// If I'm allowed to allocate memory for *ptrCh in the
heap .. Why am I not allowed to delete?
//delete [] ptrCh;

}

I know most of the folks in this group are experts and this might
sound a very stupid qn. Nevertheless, I would be able to learn from
the thoughts of the folks here..

I have read that ' const char* ptr ' means ptr can point to anything
but what it points to remains constant.

My Qns:

1. Does it mean - In the above code ptrCh is allocated 50 bytes of
memory and is it constant?

2. Would ptrCh save " ABCDE" in the allocated space in the heap -
( Isn't it only an assignment ) ?

3. If the compiler allows me to allocate memory using new why am I not
allowed to delete?

4. The most important qn.. I know there are other methods to handle
strings in C++ - like string class, RWCString ( Rogue Wave ) etc.

Assuming if in some circumstance you are required to create an array
of char's lets say 2048 char's. What is the best approach that a
programmer like you would do in C++. Please note you are not allowed
to use std::string or anything only some form of char

Would you create a
1. char testArray[2048] = "blah blah ..." ;
2. char *testArray = new char[2048]; strcpy(testArray,
"blah blah ....");
3. char *testArray = "blah blah .....";

Apologizing in advance if it sounds more of a C Qn..

Thanks,
-AY

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: A Curious Developer on
> const char* ptrCh = new char[50];
> ptrCh = "ABCDE";

You should use this instead:

char* ptrCh = new char[50];
strcpy( ptrCh, "ABCDE" );

strcpy (or strcpy_s) from <string.h> is used to copy strings.
"=" does not copy the string. "=" overwrites the heap-allocated
char[50] with a pointer to a compiler-managed string, not in the heap.


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Daniel Krügler on
On 29 Jul., 15:48, AY <techreposit...(a)gmail.com> wrote:
> This is only for my understanding... I know most of the code in here
> is wrong. But I was trying out something and am trying to make some
> sense out of it.. the code is as follows:

First question: Which compiler (including version)
are you using?

> int main( void )
> {>
> const char* ptrCh = new char[50];

This allocates an array of 50 char characters via operator new[].
The memory has so-called dynamic storage duration. The contract
is, that such memory must be released via delete[].

ptrCh is declared as a pointer to const char. This means that
we can change the contents of ptrCh (i.e. we can assign
a new address), but we cannot change the pointee
(i.e. the memory that ptrCh is pointing to) *via* ptrCh.

> ptrCh = "ABCDE";

This is syntactically well-formed, because ptrCh is a pointer
that can be reassigned. But this assignment is semantically
wrong, because ptrCh now points to memory that has *not*
been allocated via operator new[]. Every string literal has *static*
storage duration and must not be freed by the user.

To be more specific: Above reassignment is OK, unless
you attempt to provide the pointer pointing to memory
of non-dynamic storage duration to the deallocation
function operator delete[].

> // If I'm allowed to allocate memory for *ptrCh in the
> heap .. Why am I not allowed to delete?
> //delete [] ptrCh;

Because the memory that ptrCh is currently pointing to does
not have dynamic storage duration. As an example: The situation
you are describing here is not much different than this variation:

int main() {
int i = 12; // Variable i has automatic storage duration
const int* pi = &i; // OK; pi points to the memory that i refers to.
delete[] pi; // Not OK, because pi does not point to memory of
// dynamic storage duration => Undefined behaviour!
}

> I have read that ' const char* ptr ' means ptr can point to anything
> but what it points to remains constant.

This is incorrect. The meaning is, that any code that attempts
to change what ptr points to, is ill-formed. This is *no* dynamic
memory protection! It is just a static compiler "shield".
You can also use explicit means (e.g. via const_cast) to let
the compiler accept this const violation but you are running
into undefined behaviour, when the actual memory was const
and after the cast you were trying to modify the memory.

> My Qns:
>
> 1. Does it mean - In the above code ptrCh is allocated 50 bytes of
> memory and is it constant?

ptrCh gets at least 50 bytes of memory with dynamic storage
duration. This memory returned from the operator *is* mutable,
i.e. you can change what it points to, but you are assigning it
to a pointer to const, which means that the compiler will statically
reject any attempt to change the memory via ptrCh. It would be
possible to reassign the memory to a mutable pointer, though:

char* p = const_cast<char*>(ptrCh);
p[0] = 'a';

Both lines are well-formed and well-defined, *because* the actual
memory area is *not* const.

> 2. Would ptrCh save " ABCDE" in the allocated space in the heap -
> ( Isn't it only an assignment ) ?

No. The meaning is, that you reassign the pointer value of ptrCh:
It points now to the memory that the array " ABCDE" refers to.
>From a beginners p.o.v. this is a very curious effect, because
the compiler *implicitly* converts the array to a pointer! Welcome
in the world of C(++)!

If you want to copy the contents from the memory " ABCDE"
you may use strcpy:

#include <string.h>

int main() {
char* ptrCh = new char[50];
strcpy(ptrCh, " ABCDE");
// ... Do something with ptrCh
delete[] ptrCh;
}

Note that I did remove the const qualifier from
ptrCh. If I would not have done this, the compiler
would reject the following line (using strcpy),
because strcpy requires a pointer to non-const
char. This is reasonable, because it will attempt
to copy soemthing into it.

> 3. If the compiler allows me to allocate memory using new why am I not
> allowed to delete?

It is OK to do that (in fact you should do that, because otherwise
you can easily run into memory leaks), but you are required to
assign a pointer to delete[] that points to memory allocated
from new[]. In your example you did not do that: You were
providing memory of static storage duration to that operator.

> 4. The most important qn.. I know there are other methods to handle
> strings in C++ - like string class, RWCString ( Rogue Wave ) etc.

I don't think, that it is necessary to use proprietary types.
The most simple solution (and probably the recommended
one) is to use std::string instead:

#include <string>
#include <iostream>

int main()
{
using namespace std;
string s = "ABCDE";
cout<<" ptrCh = " <<ptrCh<<endl;
}

No allocation - no deallocation - std;;string is aleady managing
this correctly for you.

> Assuming if in some circumstance you are required to create an array
> of char's lets say 2048 char's. What is the best approach that a
> programmer like you would do in C++. Please note you are not allowed
> to use std::string or anything only some form of char

May I ask, why std::string is not allowed?

> Would you create a
> 1. char testArray[2048] = "blah blah ..." ;
> 2. char *testArray = new char[2048]; strcpy(testArray,
> "blah blah ....");
> 3. char *testArray = "blah blah .....";
>
> Apologizing in advance if it sounds more of a C Qn..

First, I would like to understand the reasons why std::string
is a no go - there may be false assumptions behind that
argument.

Second, if the arguments are convincing (not to use std::string),
I would use std::unique_ptr<char[]>, if my compiler supports
this type (Try header <memory>). This class takes responsibility
for the memory management.

HTH & Greetings from Bremen,

Daniel Kr�gler


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: A Curious Developer on
> "=" overwrites the heap-allocated char[50] with a pointer to a
compiler-managed string, not in the heap.

To be clear, I meant that "=" overwrites the *pointer* to the heap-
allocated string - the pointer kept in ptrCh.
The contents of the heap-allocated string are unchanged by "=".

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Mathias Gaunard on
On Jul 29, 2:48 pm, AY <techreposit...(a)gmail.com> wrote:
> Hi There,
>
> This is only for my understanding... I know most of the code in here
> is wrong. But I was trying out something and am trying to make some
> sense out of it.. the code is as follows:
>
> int main( void )
> {
>
> const char* ptrCh = new char[50];
> ptrCh = "ABCDE";
> cout<<" ptrCh = " <<ptrCh<<endl;
>
> // If I'm allowed to allocate memory for *ptrCh in the
> heap .. Why am I not allowed to delete?
> //delete [] ptrCh;
>
> }

What you probably wanted to do was strcpy(ptrCh, "ABCDE"), not ptrCH =
"ABCDE".



--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]