C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

how do you define a char *** on the fly?

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
Rob B
Guest





PostPosted: Mon Jul 26, 2004 10:52 pm    Post subject: how do you define a char *** on the fly? Reply with quote



I'm trying to read through a file and split out the line into an array
of char arrays by field delimiter. Then keep all that in another
array that has an index equal to the number of lines in a file. I
need them in pointers for further processing but so far I haven't
figured out how to do it. Is this possible?


// declare at top
char *** threeDeep = 0;

// do some work
threeDeep = (char ***) new char;

// read loop
for (int i = 0; i < someLargeNum; i++)
{
threeDeep[i] = (char **) new char;

threeDeep[i][0] = new char[MAX_FIELD_SIZE];
strcpy( threeDeep[i][0], "stringIreadIn");
threeDeep[i][1] = new char[MAX_FIELD_SIZE];
strcpy( threeDeep[i][1], "stringIreadIn2");
}

// cleanup
for (int i = 0; i < someLargeNum; i++)
{
for (int j = 0; j < howManyFieldsIhad; j++)
{
delete [] threeDeep[i][j];
}
delete [] threeDeep[i];
}
delete threeDeep;

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Pete Becker
Guest





PostPosted: Tue Jul 27, 2004 10:48 am    Post subject: Re: how do you define a char *** on the fly? Reply with quote



Rob B wrote:
Quote:

I'm trying to read through a file and split out the line into an array
of char arrays by field delimiter. Then keep all that in another
array that has an index equal to the number of lines in a file. I
need them in pointers for further processing but so far I haven't
figured out how to do it. Is this possible?


http://www.petebecker.com/js199911.html

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)

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

Back to top
Ulrich Eckhardt
Guest





PostPosted: Tue Jul 27, 2004 11:02 am    Post subject: Re: how do you define a char *** on the fly? Reply with quote



Rob B wrote:
Quote:
// declare at top
char *** threeDeep = 0;

// do some work
threeDeep = (char ***) new char;

Stop right here. Doing such casts shows that you have not yet understood
the concept behind new and casting. Never ever use casts unless you know
you need them and that there is no proper solution. They are a last resort
to force the compiler to accept some code and a beginner never needs them.

Further, take a look at std::string and std::list or std::vector. Also, if
you are learning from a book, look at the reviews at accu.org and consider
dumping that book if it didn't at least get a 'recommended'.

Uli

--
Questions ?
see C++-FAQ Lite: http://parashift.com/c++-faq-lite/ first !


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

Back to top
Andreas Scherer
Guest





PostPosted: Tue Jul 27, 2004 3:42 pm    Post subject: Re: how do you define a char *** on the fly? Reply with quote

Quote:
I'm trying to read through a file and split out the line into an array
of char arrays by field delimiter. Then keep all that in another
array that has an index equal to the number of lines in a file.

Have a look at the "tokenizer" library at www.boost.org (and use some
standard containers to store the results per line and token).

Take care,
Andreas

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

Back to top
Gareth Stockwell
Guest





PostPosted: Tue Jul 27, 2004 3:43 pm    Post subject: Re: how do you define a char *** on the fly? Reply with quote

[email]EmperorRob (AT) yahoo (DOT) com[/email] (Rob B) wrote in message news:<50942500.0407261259.74f94fb1 (AT) posting (DOT) google.com>...
Quote:
I'm trying to read through a file and split out the line into an array
of char arrays by field delimiter. Then keep all that in another
array that has an index equal to the number of lines in a file. I
need them in pointers for further processing but so far I haven't
figured out how to do it. Is this possible?


// declare at top
char *** threeDeep = 0;


Rob,

Quote:
// do some work
threeDeep = (char ***) new char;

What on earth is this?? You're dynamically allocating a new char,
getting a pointer to it (i.e. a char*), then casting it to a char***.
Any time you write a cast, think hard about it several times before
moving on...

The line should be

threeDeep = new char**[someLargeNum];

With the allocation of each threeDeep[i] being something like

threeDeep[i] = new char*[someOtherLargeNum];

Also, your first two deletes are OK, but threeDeep itself refers to an
array as well, so you should use empty [] bracket when you get rid of
it too

delete [] threeDeep;

All this may be better handled using STL components: instead of your
char*** array, you could dispense with tricky new/deletes and work
with these instead:

typedef std::string word;
typedef std::vector<word> line;
typedef std::vector<line> file_contents;

HTH
Gareth

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

Back to top
Falk Tannhäuser
Guest





PostPosted: Tue Jul 27, 2004 3:46 pm    Post subject: Re: how do you define a char *** on the fly? Reply with quote

Rob B wrote:
Quote:


// do some work
threeDeep = (char ***) new char;

A golden rule: Never cast the result of 'new'!

What you are doing above is to allocate 1 byte, and then
you try to use it as a pointer which most likely occupies
more storage (for instance, 4 bytes on many popular platforms).

What you want to do is

// Allocate space for one pointer (not very useful,
// it would be better to use an automatic variable 'char** twoDeep'
char*** threeDeep = new char**;
// use threeDeep ...
delete c;

or
// Allocate an array of 10 'char**' pointers
threeDeep = new char**[10];
// ... use threeDeep ...
delete[] threeDeep;

Didn't check the rest of your post...

Falk

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

Back to top
Ahti Legonkov
Guest





PostPosted: Tue Jul 27, 2004 4:26 pm    Post subject: Re: how do you define a char *** on the fly? Reply with quote

Rob B wrote:

Quote:
I'm trying to read through a file and split out the line into an array
of char arrays by field delimiter. Then keep all that in another
array that has an index equal to the number of lines in a file. I
need them in pointers for further processing but so far I haven't
figured out how to do it.

No, you don't need pointers. Unless of course you have some third
party library that requires it.

Quote:
Is this possible?

Yes, it is possible. But if you use new, don't cast that pointer to
anything - what new returns has the right type. At least it is when
you new a correct type :)

Quote:
// declare at top
char *** threeDeep = 0;
threeDeep = (char ***) new char;

new char**[n];

Quote:
threeDeep[i] = (char **) new char;

new char*[n];

Quote:
...

But why are you using char pointers anyway? There are std::string
and std::vector that make life much easier.

std::vector<std::vector threeDeep;

// read loop
for (int i = 0; i < someLargeNum; ++i)
{
std::vector
std::string s1 = "stringIreadIn", s2 = "stringIreadIn2";
tmp.push_back(s1);
tmp.push_back(s2);

threeDeep.push_back(tmp);
}

// cleanup
// not needed :)

--
Ahti Legonkov


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

Back to top
Rob B
Guest





PostPosted: Wed Jul 28, 2004 10:01 pm    Post subject: Re: how do you define a char *** on the fly? Reply with quote

Thanks for the help guys, I really appreciate it. The reason I am
using char pointers is b/c I need a char ** to pass to a function
later in my process otherwise I would be using a container. I think
I've found a good solution for it by using an array of structs that
each hold a char ** pointer.

One more question that I have; is this code safe?

char ** line = new char *;

for (int i = 0; i < 10; ++i)
{
line[i] = new char[64];
}


Or do I need to specify and explicit size on the new:
char ** line = new char *[10];

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Conrad S.
Guest





PostPosted: Thu Jul 29, 2004 10:28 am    Post subject: Re: how do you define a char *** on the fly? Reply with quote


"Rob B" <EmperorRob (AT) yahoo (DOT) com> schreef in bericht
news:50942500.0407280818.4257bd2 (AT) posting (DOT) google.com...
Quote:
Thanks for the help guys, I really appreciate it. The reason I am
using char pointers is b/c I need a char ** to pass to a function

You can still use a container to hold objects of type char**.
typedef char** Line;
typedef std::vector< Line > TheBook;

TheBool theBook;


And then call your function like this:

SomeFunc( theBook[ LineIndex ] /*char** */ );


Quote:
later in my process otherwise I would be using a container. I think
I've found a good solution for it by using an array of structs that
each hold a char ** pointer.

One more question that I have; is this code safe?

char ** line = new char *;

This allocates memory for 1 pointer to character. No more! The next memory
location is _not_ yours.

Quote:

for (int i = 0; i < 10; ++i)
{
line[i] = new char[64];
}


Or do I need to specify and explicit size on the new:
char ** line = new char *[10];

Yes.

Antoon



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

Back to top
Matt Young
Guest





PostPosted: Thu Jul 29, 2004 3:13 pm    Post subject: Re: how do you define a char *** on the fly? Reply with quote

[email]EmperorRob (AT) yahoo (DOT) com[/email] (Rob B) wrote in message news:<50942500.0407280818.4257bd2 (AT) posting (DOT) google.com>...
Quote:
Thanks for the help guys, I really appreciate it. The reason I am
using char pointers is b/c I need a char ** to pass to a function
later in my process otherwise I would be using a container. I think
I've found a good solution for it by using an array of structs that
each hold a char ** pointer.

One more question that I have; is this code safe?

char ** line = new char *;

for (int i = 0; i < 10; ++i)
{
line[i] = new char[64];
}


Or do I need to specify and explicit size on the new:
char ** line = new char *[10];

It's not safe because arrays and pointers are not quite the same
thing. Although you can usually treat an array variable as a const
pointer, you can't do the opposite. Declaring/creating a pointer does
not allocate any memory for it to point at. Declaring/creating an
array on the other hand reserves memory (eg on the stack for an
automatic variable or on the free store if you use new) to store the
elements of the array. Eg try the following:

#include int main(int argc, char** argv) {
// Stack variables to keep example simple
char * pointer;
char array[10];

std::cout << "Pointer to char takes " << sizeof(pointer) <<
" bytes, array of 10 chars takes " << sizeof(array) <<
" bytes." << std::endl;

// array is (almost) synonymous with &array[0] and points to the
// start of the array storage
std::cout << "array = " << static_cast ", &array[0] = " << static_cast
// Similarly array + 5 is synonymous with &array[5]
std::cout << "array + 5 = " << static_cast ", &array[5] = " << static_cast
// pointer doesn't yet point to anything. We'll get a compiler
// warning if we don't assign to pointer before using it. But we
// can point it to (the first element of) the array.
pointer = array;
std::cout << "pointer = array = &array[0] = " <<
static_cast
// We can change what pointer points at...
pointer = &array[5];
std::cout << "pointer = &array[5] = array + 5 = " <<
static_cast
// ...but we can't change what array points at. Eg you'll get a
// compiler warning if you uncomment the following line:
//array = pointer;

return 0;
}

By the way, going back to your code fragment, if you don't know in
advance how big line needs to be, you can declare it as a vector --
and still pass it as char ** to your library function:

std::vector for (int ii = 0; ii < 10; ++ii) {
line.push_back(&new char[64]);
}
...
libraryFunction(&line[0]);

The standard guarantees that vector entries are contiguous, in order
that you can pass it in like this to legacy functions expecting
pointers/arrays.

HTH

Matt

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

Back to top
Andreas Scherer
Guest





PostPosted: Thu Jul 29, 2004 3:21 pm    Post subject: Re: how do you define a char *** on the fly? Reply with quote

Quote:
The reason I am using char pointers is b/c I need a char ** to
pass to a function later in my process ...

Pitty you, if it's an external interface that you can't change (or
worse, if it's a function that you intend to define yourself).

Quote:
One more question that I have; is this code safe?

No, it's not.

Quote:
Or do I need to specify and explicit size on the new:
char ** line = new char *[10];

Yes, that looks more like correct code (apart from the missing
"delete[]"s), but ... assuming that your external function looks
something like

void f( const char** array, const size_t array_size ) { ... }

you still don't need to mess with "new/delete" (make that "delete[]"
for all those terrible "dynamic arrays"!). According to the c.l.c++.m
FAQ, you can use

std::vector< const char* > array;
array.push_back( "First string" );
array.push_back( "Second string" );

if ( ! array.empty() )
f( &array[ 0 ], array.size() );

Take care,
Andreas

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

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.