 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Rob B Guest
|
Posted: Mon Jul 26, 2004 10:52 pm Post subject: how do you define a char *** on the fly? |
|
|
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
|
Posted: Tue Jul 27, 2004 10:48 am Post subject: Re: how do you define a char *** on the fly? |
|
|
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
|
Posted: Tue Jul 27, 2004 11:02 am Post subject: Re: how do you define a char *** on the fly? |
|
|
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
|
Posted: Tue Jul 27, 2004 3:42 pm Post subject: Re: how do you define a char *** on the fly? |
|
|
| 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
|
Posted: Tue Jul 27, 2004 3:43 pm Post subject: Re: how do you define a char *** on the fly? |
|
|
[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
|
Posted: Tue Jul 27, 2004 3:46 pm Post subject: Re: how do you define a char *** on the fly? |
|
|
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
|
Posted: Tue Jul 27, 2004 4:26 pm Post subject: Re: how do you define a char *** on the fly? |
|
|
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.
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];
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
|
Posted: Wed Jul 28, 2004 10:01 pm Post subject: Re: how do you define a char *** on the fly? |
|
|
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
|
Posted: Thu Jul 29, 2004 10:28 am Post subject: Re: how do you define a char *** on the fly? |
|
|
"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
|
Posted: Thu Jul 29, 2004 3:13 pm Post subject: Re: how do you define a char *** on the fly? |
|
|
[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
|
Posted: Thu Jul 29, 2004 3:21 pm Post subject: Re: how do you define a char *** on the fly? |
|
|
| 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 |
|
 |
|
|
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
|
|