Dynamic array

P

Paul

Hi all,

I have a string which I want to break into a char[] array, is the
following way of doing this ok:

const char* test = new char[sQuery.length()];

test = sQuery.c_str();

and finally:

delete[] test;


Would this cause any issues or memory leaks?

Thanks.
 
V

Victor Bazarov

Paul said:
I have a string which I want to break into a char[] array, is the
following way of doing this ok:

const char* test = new char[sQuery.length()];

test = sQuery.c_str();

and finally:

delete[] test;


Would this cause any issues or memory leaks?

You bet. Plenty. First off, you allocate an array of unintialised
constant characters (i.e. you won't be able to even fill the array
with any meaningful values). Second, you override the value by some
pointer you get from the string's 'c_str' member (thus losing the
value obtained from the 'new[]'), which you then try to delete[].

(a) You don't allocate enough.
(b) Your characters are not copied from the string into the allocated
buffer, instead the address of the buffer is lost.
(c) You attempt to delete the array you didn't allocate.

Memory leaks? If you're lucky. Your program actually has undefined
behaviour at 'delete[]'.

Here is how you should do it, compare it to your version and try to
learn something:

char* test = new char[sQuery.length() + 1]();
strcpy(test, sQuery.c_str());
... // use 'test'
delete[] test;

Now, if your 'sQuery' by some chance contains null characters as
its contents, you are likely not getting any characters from the
string that follow the first null character. But that scenario
is unlikely.

V
 
D

Daniel Kraft

Paul said:
Hi all,

I have a string which I want to break into a char[] array, is the
following way of doing this ok:

const char* test = new char[sQuery.length()];

test = sQuery.c_str();

This assigns the pointer to a new location, leaking your allocated
memory. Use copy/memcpy/strcpy or the like instead.
and finally:

delete[] test;

I'm not quite sure what this really does (depends probably on your STL
implementation), but this frees the pointer returned from c_str() which
is probably not a very good idea.
 
J

Jim Langston

Paul said:
Hi all,

I have a string which I want to break into a char[] array, is the
following way of doing this ok:

const char* test = new char[sQuery.length()];

test = sQuery.c_str();

and finally:

delete[] test;


Would this cause any issues or memory leaks?

You becha. And it probalby wouldn't do what you want anyway.

1. const char* test = new char[sQuery.length()];
You didn't allocate enough bytes. Since it's going to be a c-style string,
you need to add one more char for the null terminator.
2. you're making it const, so you can't change it.

char* test = new char[sQuery.length() + 1];

3. test = sQuery.c_str();
You are overwriting the pointer. You just lost the pointer to the memory
returned by new since you are now assigning it to the const char* reutrned
by c_str(). You need to copy the data, not the pointer. There is an old
c-function for this ( a number of them). strcpy (string copy).

strcpy( test, sQuery.c_str() );

Your delete[] test; is correct.

Incidently, there should be no reason to have to copy a std::string to a
cstyle string. If you have to copy it, copy the std::string.

I have found times I had to use a char[] instead of a std::string, and that
was because some cfunction copies into a char array and I can't really
provide that with std::string. I could with std::vector, but usually wind
up using char[] for this. I've not yet found any reason to have to copy
from a std::string to a char array though.
 
P

Paul

I have a string which I want to break into a char[] array, is the
following way of doing this ok:
const char* test = new char[sQuery.length()];
test = sQuery.c_str();
and finally:
delete[] test;
Would this cause any issues or memory leaks?

You becha. And it probalby wouldn't do what you want anyway.

1. const char* test = new char[sQuery.length()];
You didn't allocate enough bytes. Since it's going to be a c-style string,
you need to add one more char for the null terminator.
2. you're making it const, so you can't change it.

char* test = new char[sQuery.length() + 1];

3. test = sQuery.c_str();
You are overwriting the pointer. You just lost the pointer to the memory
returned by new since you are now assigning it to the const char* reutrned
by c_str(). You need to copy the data, not the pointer. There is an old
c-function for this ( a number of them). strcpy (string copy).

strcpy( test, sQuery.c_str() );

Your delete[] test; is correct.

Incidently, there should be no reason to have to copy a std::string to a
cstyle string. If you have to copy it, copy the std::string.

I have found times I had to use a char[] instead of a std::string, and that
was because some cfunction copies into a char array and I can't really
provide that with std::string. I could with std::vector, but usually wind
up using char[] for this. I've not yet found any reason to have to copy
from a std::string to a char array though.

Thanks for the replies all. I was using char[] as I needed to parse
the string on a character basis. The string would be a query from a
search page and it could contain words or phrases sorrounded by speech
marks or contain other tokens such as: + - etc So this seemed the best
way to do it: Firstly parse the string on a character basis through a
small algorithm which would break it into tokens based upon their
placement, open/closed speech marks etc, then place the tokens into a
collection as strings, which was looped through to generate part of a
large SQL query.
The reason for using const char* was because the compiler was throwing
up errors on this line of code: test = sQuery.c_str();, saying it
couldnt convert a char to a const char.
It compiled and worked, but I was worried about memory leaks etc, and
from all your answers, it seems I was right to do so. Thanks again :).
 
J

Jim Langston

Paul said:
I have a string which I want to break into a char[] array, is the
following way of doing this ok:
const char* test = new char[sQuery.length()];
test = sQuery.c_str();
and finally:
delete[] test;
Would this cause any issues or memory leaks?

You becha. And it probalby wouldn't do what you want anyway.

1. const char* test = new char[sQuery.length()];
You didn't allocate enough bytes. Since it's going to be a c-style
string,
you need to add one more char for the null terminator.
2. you're making it const, so you can't change it.

char* test = new char[sQuery.length() + 1];

3. test = sQuery.c_str();
You are overwriting the pointer. You just lost the pointer to the memory
returned by new since you are now assigning it to the const char*
reutrned
by c_str(). You need to copy the data, not the pointer. There is an old
c-function for this ( a number of them). strcpy (string copy).

strcpy( test, sQuery.c_str() );

Your delete[] test; is correct.

Incidently, there should be no reason to have to copy a std::string to a
cstyle string. If you have to copy it, copy the std::string.

I have found times I had to use a char[] instead of a std::string, and
that
was because some cfunction copies into a char array and I can't really
provide that with std::string. I could with std::vector, but usually
wind
up using char[] for this. I've not yet found any reason to have to copy
from a std::string to a char array though.

Thanks for the replies all. I was using char[] as I needed to parse
the string on a character basis. The string would be a query from a
search page and it could contain words or phrases sorrounded by speech
marks or contain other tokens such as: + - etc So this seemed the best
way to do it: Firstly parse the string on a character basis through a
small algorithm which would break it into tokens based upon their
placement, open/closed speech marks etc, then place the tokens into a
collection as strings, which was looped through to generate part of a
large SQL query.
The reason for using const char* was because the compiler was throwing
up errors on this line of code: test = sQuery.c_str();, saying it
couldnt convert a char to a const char.
It compiled and worked, but I was worried about memory leaks etc, and
from all your answers, it seems I was right to do so. Thanks again :).

It is just as easy, if not easier, to parse character by character using a
std::string as it is using a c-style array. In fact, std::string provides
us find_first_of and other neat functions, and we can pass the string into a
stringstream for even easier/neater things.

Show us what you're doing with test and we can probalby show you easy ways
to do it in C++ style strings.
 
O

Old Wolf

Paul said:
const char* test = new char[sQuery.length()];

First off, you allocate an array of unintialised
constant characters (i.e. you won't be able to
even fill the array with any meaningful values).

Not true, the array is of non-const chars. It is
only the pointer 'test' that has type (const char *).
You could still write stuff like:
strcpy( const_cast<char *>(test), "silly" );
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,291
Messages
2,571,455
Members
48,132
Latest member
KatlynC08

Latest Threads

Top