How to populate an array of char* pointer dymanically?

S

silverburgh.meryl

In my code, I have an array of char* pointer which is populated
statically:

void function1() {
char *ppsz_argv2[] = { "abc" ,
"def",
"dummy"};
//...
}

But how can I populated it dynamically?

void function1(string& str1, string& str2, string& str3) {

char* ppsz_arg2[] = new char[3]; // how can I allocate memory for the
array of char* here?
ppsz_arg2[0] = str1.c_str();
ppsz_arg2[1] = str2.c_str();
ppsz_arg2[2] = str3.c_str();

Thank you for any help.
 
G

Gianni Mariani

In my code, I have an array of char* pointer which is populated
statically:

void function1() {
char *ppsz_argv2[] = { "abc" ,
"def",
"dummy"};
//...
}

But how can I populated it dynamically?

void function1(string& str1, string& str2, string& str3) {

char* ppsz_arg2[] = new char[3]; // how can I allocate memory for the
array of char* here?

Here you're allocating an array of 3 chars. You want to instead
allocate an array of 3 *pointers* to const chars.
ppsz_arg2[0] = str1.c_str();
ppsz_arg2[1] = str2.c_str();
ppsz_arg2[2] = str3.c_str();

Best way by far to do this is use std::vector.

std::vector<const char *> vec( 3 );

vec[0] = str1.c_str();
vec[1] = str2.c_str();
vec[2] = str3.c_str();

Now you don't have probs will freeing the memory afterwoods.

BTW - anything that modifies str1, str2 and str3 will invalidate the
pointers placed in the vector so make sure they are never touched while
you're using vec.
 
S

silverburgh.meryl

In my code, I have an array of char* pointer which is populated
statically:
void function1() {
char *ppsz_argv2[] = { "abc" ,
"def",
"dummy"};
//...
}
But how can I populated it dynamically?
void function1(string& str1, string& str2, string& str3) {
char* ppsz_arg2[] = new char[3]; // how can I allocate memory for the
array of char* here?

Here you're allocating an array of 3 chars. You want to instead
allocate an array of 3 *pointers* to const chars.
ppsz_arg2[0] = str1.c_str();
ppsz_arg2[1] = str2.c_str();
ppsz_arg2[2] = str3.c_str();

Best way by far to do this is use std::vector.

std::vector<const char *> vec( 3 );

vec[0] = str1.c_str();
vec[1] = str2.c_str();
vec[2] = str3.c_str();

Now you don't have probs will freeing the memory afterwoods.

BTW - anything that modifies str1, str2 and str3 will invalidate the
pointers placed in the vector so make sure they are never touched while
you're using vec.

Thanks. But I need to call a function which takes 'char* ppsz_arg2[]'
later on.

How can I convert from 'std::vector<const char *>' to 'char*
ppsz_arg2[]'?

Thanks for any other pointers.
 
B

BobR

In my code, I have an array of char* pointer which is populated
statically:
void function1() {
char *ppsz_argv2[] = { "abc", "def", "dummy"};
//...
}

Best way by far to do this is use std::vector.

std::vector<const char *> vec( 3 );
vec[0] = str1.c_str();
vec[1] = str2.c_str();
vec[2] = str3.c_str();

Now you don't have probs will freeing the memory afterwoods.
BTW - anything that modifies str1, str2 and str3 will invalidate the
pointers placed in the vector so make sure they are never touched while
you're using vec.

Thanks. But I need to call a function which takes 'char* ppsz_arg2[]'
later on.
How can I convert from 'std::vector<const char *>' to 'char*
ppsz_arg2[]'?
Thanks for any other pointers.

void CharFunc( char const *arg[], std::size_t size ){
return;
}

{
std::vector< char const * > Vppsz(3);
// .... fill vector
CharFunc( &Vppsz.at(0), Vppsz.size() );
}

Or, even better, change to:

void CharFunc( std::vector< char const *> const &ppsz ){
return;
}

{
std::vector< char const * > Vppsz(3);
// .... fill vector
CharFunc( Vppsz );
}

Best yet:

void CharFunc( std::vector< std::string > /*const*/ &ppsz ){
return;
}

{
std::vector< std::string > Vppsz(3);
// .... fill vector
CharFunc( Vppsz );
}
 
S

silverburgh.meryl

(e-mail address removed) wrote:
In my code, I have an array of char* pointer which is populated
statically:
void function1() {
char *ppsz_argv2[] = { "abc", "def", "dummy"};
//...
}
Best way by far to do this is use std::vector.
std::vector<const char *> vec( 3 );
vec[0] = str1.c_str();
vec[1] = str2.c_str();
vec[2] = str3.c_str();
Now you don't have probs will freeing the memory afterwoods.
BTW - anything that modifies str1, str2 and str3 will invalidate the
pointers placed in the vector so make sure they are never touched while
you're using vec.
Thanks. But I need to call a function which takes 'char* ppsz_arg2[]'
later on.
How can I convert from 'std::vector<const char *>' to 'char*
ppsz_arg2[]'?
Thanks for any other pointers.

void CharFunc( char const *arg[], std::size_t size ){
return;
}

{
std::vector< char const * > Vppsz(3);
// .... fill vector
CharFunc( &Vppsz.at(0), Vppsz.size() );

}

Or, even better, change to:

void CharFunc( std::vector< char const *> const &ppsz ){
return;
}

{
std::vector< char const * > Vppsz(3);
// .... fill vector
CharFunc( Vppsz );

}

Best yet:

void CharFunc( std::vector< std::string > /*const*/ &ppsz ){
return;
}

{
std::vector< std::string > Vppsz(3);
// .... fill vector
CharFunc( Vppsz );

}

Thanks. I get garabage when I try to print out arg[] in my CharFunc():

void CharFunc( char const *arg[], std::size_t size ){

// when I print out the content of arg[] here, I get garbage for
arg[1] (just arg[1])
return;
}

void anotherFun(string& str){
{

std::eek:stringstream apath;
apath << "http://";

apath << str;

apath << '\0';

std::vector< const * > Vppsz(3);


vec[0] = "abc";
vec[1] = (char*)apath.str().c_str();
vec[2] = "hello";

CharFunc( &Vppsz.at(0), Vppsz.size() );

}

Can you please tell me why is that? Thank you
 
R

Robbie Hatley

Silverburgh Meryl said:
void function1(string& str1, string& str2, string& str3)
{
// how can I allocate memory for the array of char* here?
char* ppsz_arg2[] = new char[3];
...
}

Why do you need dynamic allocation if the number of elements
is always three?

If you're *sure* you need dynamic allocation for the array,
then allocate more array space than you think you'll need.
(If you run out of space, you'll have to re-allocate, which
will get very messy.)

Your syntax has multiple errors, though. It should look
more like this:

// new-array-test.cpp
#include <iostream>
#include <string>
#include <cstring>
#include <new>

void
function1
(
std::string const & str1,
std::string const & str2,
std::string const & str3
)
{
char ** ppsz_arg2 = new char* [50];

ppsz_arg2[0] = new char [str1.size() + 1];
std::strcpy(ppsz_arg2[0], str1.c_str());

ppsz_arg2[1] = new char [str2.size() + 1];
std::strcpy(ppsz_arg2[1], str2.c_str());

ppsz_arg2[2] = new char [str3.size() + 1];
std::strcpy(ppsz_arg2[2], str3.c_str());

std::cout << "First string is: " << ppsz_arg2[0] << std::endl;
std::cout << "Second string is: " << ppsz_arg2[1] << std::endl;
std::cout << "Third string is: " << ppsz_arg2[2] << std::endl;
return;
}

int main (int, char * Luthien[])
{
function1(Luthien[1], Luthien[2], Luthien[3]);
return 0;
}



If I then type, at the command prompt:

new-array-test Able Baker Charly

It prints:

First string is: Able
Second string is: Baker
Third string is: Charly

But if you're only going to have 3 elements, you should
use a static array.

Replace this line:

char ** ppsz_arg2 = new char* [50];


with this line:

char *ppsz_arg2[3];


(Better yet, dump all usage of C-style char* and use
std::string instead, throughout your program. It's
sooooooo much easier.)
 
G

Gianni Mariani

Can you please tell me why is that? Thank you

Please post exactly the code you're using to demonstrate the errors
because the code you posted in your last post won't compile.

Also, make sure you don't touch the string after placing it in the
vector and the vector has yet to be destroyed.
 
B

BobR

Thanks. I get garabage when I try to print out arg[] in my CharFunc():

void CharFunc( char const *arg[], std::size_t size ){
// when I print out the content of arg[] here, I get garbage for
arg[1] (just arg[1])
return;
}

void anotherFun(string& str){ {
std::eek:stringstream apath;
apath << "http://";
apath << str;
apath << '\0';
std::vector< const * > Vppsz(3);
vec[0] = "abc";
vec[1] = (char*)apath.str().c_str();
vec[2] = "hello";
CharFunc( &Vppsz.at(0), Vppsz.size() );
}

Can you please tell me why is that? Thank you

You need to put something *in* the vector!!!

#include <iostream>
#include <vector>
#include <ostream>

void CharFunc( char const *arg[], std::size_t size,
std::eek:stream &out ){
for( std::size_t i(0); i < size; ++i ){
out<<arg<<std::endl;
}
return;
}

int main(){ using std::cout; // for NG post

std::vector< char const *> Vppsz(3);
Vppsz.at(0) = "abc"; // NOT vec[]
Vppsz.at(1) = "def";
Vppsz.at(2) = "dummy";
CharFunc( &Vppsz.at(0), Vppsz.size(), cout );
return 0;
} // main()

Note how I have posted a *complete*, compilable program, which demonstrates
a problem (if there were one, in which case I would also post the first 3 or
4 errors). That's how you should post in this NG.

When you post little bits of here and there code, it's hard to determine
exactly what errors you are getting (and/or why).
 
B

BobR

.... additional ...

Learn to use std::string.....

std::string apath( "http://" );
apath += str;
// apath += '\0'; // not needed, use 'apath.c_str()'


Now look how easy it is with std:string...
#include <iostream>
#include <vector>
#include <ostream>
#include <string>

void FillVector( std::vector< std::string > &vec){ // non-const here
vec.push_back( "abc" );
vec.push_back( "def" );
vec.push_back( "dummy" );
return;
} // FillVector(vector<string>&)

void PrintVector( std::vector< std::string > const &vec,
std::eek:stream &out ){
for( std::size_t i(0); i < vec.size(); ++i ){ // vector has the size
out<<vec.at( i )<<std::endl;
// out<<vec.[ i ]<<std::endl; // ok here, index is safe
} // for(i)
return;
} // PrintVector(vector said:
int main(){ using std::cout; // for NG post

std::vector< std::string > MyVec;
FillVector( MyVec );
PrintVector( MyVec, cout );
 
S

silverburgh.meryl

... additional ...

Learn to use std::string.....

std::string apath( "http://" );
apath += str;
// apath += '\0'; // not needed, use 'apath.c_str()'

Now look how easy it is with std:string...
#include <iostream>
#include <vector>
#include <ostream>

#include <string>

void FillVector( std::vector< std::string > &vec){ // non-const here
vec.push_back( "abc" );
vec.push_back( "def" );
vec.push_back( "dummy" );
return;
} // FillVector(vector<string>&)

void PrintVector( std::vector< std::string > const &vec,
std::eek:stream &out ){
for( std::size_t i(0); i < vec.size(); ++i ){ // vector has the size
out<<vec.at( i )<<std::endl;
// out<<vec.[ i ]<<std::endl; // ok here, index is safe
} // for(i)
return;
} // PrintVector(vector said:
int main(){ using std::cout; // for NG post

std::vector< std::string > MyVec;
FillVector( MyVec );
PrintVector( MyVec, cout );
return 0;
} // main()
Bob,

Thank you very much for your help. i have one more question:
void FillVector( std::vector< std::string > &vec){
vec.push_back( "abc" );
vec.push_back( "def" );
vec.push_back( "dummy" );

}

Where does these string "abc", "def", "dummy" allocated? Stack or
heap?
And do i need to call destructor for those strings?

Thank you.
 
B

BobR

... additional ...
[snip]
Learn to use std::string.....
Now look how easy it is with std:string...
#include <iostream>
#include <vector>
#include <ostream>
#include <string>

void FillVector( std::vector< std::string > &vec){ // non-const here
vec.push_back( "abc" );
vec.push_back( "def" );
vec.push_back( "dummy" );
return;
} // FillVector(vector<string>&)

void PrintVector( std::vector< std::string > const &vec,
std::eek:stream &out ){
for( std::size_t i(0); i < vec.size(); ++i ){ // vector has the size
out<<vec.at( i )<<std::endl;
// out<<vec.[ i ]<<std::endl; // ok here, index is safe
} // for(i)
return;
} // PrintVector(vector said:
int main(){ using std::cout; // for NG post
std::vector< std::string > MyVec;
FillVector( MyVec );
PrintVector( MyVec, cout );
return 0;
} // main()
POVrookie

Bob,

Please do not quote sigs (the '--'), it messes with some newsreaders.
Thanks.
Thank you very much for your help. i have one more question:
void FillVector( std::vector< std::string > &vec){
vec.push_back( "abc" );
vec.push_back( "def" );
vec.push_back( "dummy" );
}

Where does these string "abc", "def", "dummy" allocated? Stack or
heap?

It's copied directly[1] into the string in the vector. As long as the vector
is alive, the strings are alive. You can modify the strings in the vector:

// using the 'vec' in 'FillVector()' function
vec.at( 1 ) = "Hello";
vec.at( 1 ) += "World!";
std::string tmp(" I want to be the leader of the ");
vec.at( 0 ) = tmp;
vec.at( 0 ) += "World!";
if( vec.at( 2 ).size() < 10 ){
vec.at( 2 ) = std::string( 20, '*' );
}
.... etc.

And do i need to call destructor for those strings?

No. When the vector gets destructed, it calls the destructors of all the
elements in it. Neat, eh? No messing with new/delete, etc., the string
handles it's data, and the vector handles it's data ( the strings).

[1] - it's a little more complex than that, but, for now, that's all you
need.
 
M

Marcus Kwok

BobR said:
Please do not quote sigs (the '--'), it messes with some newsreaders.

It should be "-- \n" (note the space before the newline). As such, your
sig delimiter is missing the space.
 
B

BobR

Marcus Kwok said:
It should be "-- \n" (note the space before the newline). As such, your
sig delimiter is missing the space.

Ya know, I've never had any trouble with 'sig quoting', either on windows or
GNU/Linux mail/newsreaders. I was told not to put 'code' below my sig, as it
doesn't show in some readers ( it was some joke code).
But, WHAT newsreader(s)? If it's just one single newsreader, shouldn't the
distributor be contacted to correct it, instead of us asking posters not to
quote sigs?

OK, rant over.
Thanks for the correction.
 
M

Marcus Kwok

BobR said:
Ya know, I've never had any trouble with 'sig quoting', either on windows or
GNU/Linux mail/newsreaders.

When the sig is properly delimited, my newsreader (tin) will
automatically strip the sig before I reply.

It seems you are using Outlook Express, which will strip blank spaces at
the ends of lines, and thus corrupt your sig delimiter. I do not know
if it has the option to turn this off.
 
B

BobR

Marcus Kwok said:
When the sig is properly delimited, my newsreader (tin) will
automatically strip the sig before I reply.

It seems you are using Outlook Express,

correction - I'm using an *old* OE. said:
which will strip blank spaces at
the ends of lines, and thus corrupt your sig delimiter. I do not know
if it has the option to turn this off.

Have not found one (.. but, I didn't really look for it.).

OE does what I need, except it puts 'PGP' signed stuff as an attachment (in
some NGs), just a blank body. ;-{
 
T

Thomas J. Gritzan

BobR said:
correction - I'm using an *old* OE. <G>

Oh yeah. Why?
Have not found one (.. but, I didn't really look for it.).

OE does what I need, except it puts 'PGP' signed stuff as an attachment (in
some NGs), just a blank body. ;-{

There are people who call OE a newsreader.
There are also people who use macros and call them templates :)
 
B

BobR

Thomas J. Gritzan said:
Oh yeah. Why?

Using win98se.
( ...and NO, I will not PAY for any newer ms products. Go GNU! )
There are people who call OE a newsreader.

Did I do that? I'll have to go wash my mouth out with soap.
There are also people who use macros and call them templates :)

Not me, I hate macros[1]! <G>

[1] - other than include-guards, or compile 'directives' (#if, #else,
#endif).
 
J

James Kanze

It should be "-- \n" (note the space before the newline). As
such, your sig delimiter is missing the space.

Note that Google messes this up sometimes. I've tried on my own
postings: the space is present in the message as it appears, but
when you hit the reply button, it gets stripped, and the sig
remains.

IMHO, this is (or should not be) a major problem. You edit the
posting you are replying to anyway, to remove the unnecessary
parts. The sig is just one more unnecessary part which needs
removing.
 
M

Marcus Kwok

James Kanze said:
Note that Google messes this up sometimes. I've tried on my own
postings: the space is present in the message as it appears, but
when you hit the reply button, it gets stripped, and the sig
remains.

Yes, I've seen your posts about it in the past and I know you've
earnestly tried very hard to figure out where the problem is. It is
unfortunate that Google gets this wrong (if it is indeed caused by the
Google chain of posting).
 
T

Thomas J. Gritzan

BobR said:
Did I do that? I'll have to go wash my mouth out with soap.

No, but why using it then?
I switched from OE to Thunderbird some time ago and I found that they are
used quite equally. But without the bugs.
There are also people who use macros and call them templates :)

Not me, I hate macros[1]! <G>

I was refering to another thread about "C++ templates" and "macro templates".
[1] - other than include-guards, or compile 'directives' (#if, #else,
#endif).

Valid usage.

Your signature delimiter is broken, too.
 

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
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top