Pointer to array of char

T

techie

I'm creating a class BookType that will store information about books. Each
book type can have up to 4 authors.

I defined a new type for an array of char:

typedef char array4_t[25];

This will hold 25 characaters

I declared a 2 dimensional array of char in BookType:

char m_authors[4][25];

I could have used vector but this just a practical exercise.


I have a SetAuthors function which sets the authors which accepts a pointer
to a pointer toi char (char**). It works fine.

I also have a function GetAuthors that returns a pointer to array4_t:

array4_t* BookType::GetAuthors()
{
return m_authors;
}


In my test program I want to loop through the array of strings and print the
authors. I've done this but it doesn't work well:

array4_t* authors = books->GetAuthors();
while (*authors != NULL)
{
printf(" %s ", authors);
authors++;
}

This goes into an infinite loop. Not sure why.

Can someone please tell me the best way to return a pointer to an array of
char and how to iterate through the array without using vector (or another
STL container)?
 
M

Michael

techie said:
I'm creating a class BookType that will store information about books. Each
book type can have up to 4 authors.

I defined a new type for an array of char:

typedef char array4_t[25];

This will hold 25 characaters

I declared a 2 dimensional array of char in BookType:

char m_authors[4][25];

I could have used vector but this just a practical exercise.


I have a SetAuthors function which sets the authors which accepts a pointer
to a pointer toi char (char**). It works fine.

I also have a function GetAuthors that returns a pointer to array4_t:

array4_t* BookType::GetAuthors()
{
return m_authors;
}


In my test program I want to loop through the array of strings and print the
authors. I've done this but it doesn't work well:

array4_t* authors = books->GetAuthors();
while (*authors != NULL)
{
printf(" %s ", authors);
authors++;
}


Have you set the 'one-past-the-end' value of authors to NULL somewhere??
This goes into an infinite loop. Not sure why.

Can someone please tell me the best way to return a pointer to an array of
char and how to iterate through the array without using vector (or another
STL container)?

Mike
 
K

Kai-Uwe Bux

techie said:
I'm creating a class BookType that will store information about books.
Each book type can have up to 4 authors.

I defined a new type for an array of char:

typedef char array4_t[25];

This will hold 25 characaters

I declared a 2 dimensional array of char in BookType:

char m_authors[4][25];

I could have used vector but this just a practical exercise.

Yes! Use vectors.
I have a SetAuthors function which sets the authors which accepts a
pointer
to a pointer toi char (char**). It works fine.

I also have a function GetAuthors that returns a pointer to array4_t:

array4_t* BookType::GetAuthors()
{
return m_authors;
}

You are providing raw access to the data in your class. Any client can
change the value without going through SetAuthors() since the returntype
here is not arra4_t const.

In my test program I want to loop through the array of strings and print
the
authors. I've done this but it doesn't work well:

array4_t* authors = books->GetAuthors();
while (*authors != NULL)


For this loop to terminate, you need to put a 0-pointer at the end of your
array. The compiler will not do that automagically. Very much like dealing
with 0-terminated strings, you have to do all the work.

Now, I bet you that you did not put a 0-pointer at the end of the array;
simply because I do not see a way of doing this at all: the type of your
array is char[4][25] and not actually (char*)[4]. Note the following funny
thing:

typedef char array4_t[25];

int main ( void ) {
array4_t xxx;
if ( xxx == NULL ) {}; // no error
xxx = NULL; // compiler error
}

{
printf(" %s ", authors);

You really want to do it the C-way, don't you?
authors++;
}

This goes into an infinite loop. Not sure why.


One of the key differences of vectors and arrays: arrays have no idea about
their length. If you allocate an array

T* t_arr = new T [n];

and you happen to forget the value of n, there will be no way to retrieve it
from t_arr. You have to keep track of the array size yourself. That can be
done in several ways, none of which will be implemented automagically for
you by the compiler:

a) keep the length and iterate from t_arr[0] to t_arr[length]
b) as a variant: store a past-end pointer.
c) put a special terminating value in the last slot of the array.
[The 0-terminated C-strings use this]
d) some other scheme.

Can someone please tell me the best way to return a pointer to an array of
char and how to iterate through the array without using vector (or another
STL container)?

The best way is to use a vector.


Best

Kai-Uwe Bux
 
J

John Harrison

techie said:
I'm creating a class BookType that will store information about books. Each
book type can have up to 4 authors.

I defined a new type for an array of char:

typedef char array4_t[25];

This will hold 25 characaters

Why call it array4_t? Why not char_array_25_t (for instance). Confused
naming is often a symptom of confused thinking. In this case I would you
you are confusing what the type declaration declares (an array of 25)
with how you are going to use it (in an array of 4).
I declared a 2 dimensional array of char in BookType:

char m_authors[4][25];

Having gone to the trouble of declaring array4_t why not use it?

array4_t m_authors[4];
I could have used vector but this just a practical exercise.


I have a SetAuthors function which sets the authors which accepts a pointer
to a pointer toi char (char**). It works fine.

I also have a function GetAuthors that returns a pointer to array4_t:

array4_t* BookType::GetAuthors()
{
return m_authors;
}


In my test program I want to loop through the array of strings and print the
authors. I've done this but it doesn't work well:

array4_t* authors = books->GetAuthors();
while (*authors != NULL)
{
printf(" %s ", authors);
authors++;
}

This goes into an infinite loop. Not sure why.


Because *authors never equals NULL presumably. Why exactly are you
expecting it to?
Can someone please tell me the best way to return a pointer to an array of
char and how to iterate through the array without using vector (or another
STL container)?

There is no best way, your way looks fine.

The basic problem is that you have a scheme for storing authors but no
scheme for saying how many authors you have stored (or if you do have
such a scheme you haven't told us about it).

Somewhere in the SetAuthors function (which you didn't post) there
should be someway of saving how many authors you have.

In the loop above you seem to be assuming that the one-past-the-end
author will start with the null character. Is that right?

If that is the case then you need an array of *five* authors. Four for
the actual authors and one extra for the one-past-the-end author. You
also need to to ensure that condition holds in the SetAuthors functions.

If this doesn't solve your problem, post all the relevant code (that
means the SetAuthors function) and state clearly how you expecting the
number of authors to be saved.

john
 
A

Alf P. Steinbach

* techie:
I'm creating a class BookType that will store information about books. Each
book type can have up to 4 authors.

I defined a new type for an array of char:

typedef char array4_t[25];

This will hold 25 characaters

Instead use std::string.

I declared a 2 dimensional array of char in BookType:

char m_authors[4][25];

I could have used vector but this just a practical exercise.

Use std::vector.

I have a SetAuthors function which sets the authors which accepts a pointer
to a pointer toi char (char**). It works fine.

I also have a function GetAuthors that returns a pointer to array4_t:

array4_t* BookType::GetAuthors()
{
return m_authors;
}


In my test program I want to loop through the array of strings and print the
authors. I've done this but it doesn't work well:

array4_t* authors = books->GetAuthors();
while (*authors != NULL)


'authors' is of type 'array4_t*'.

'*authors' is of type 'array4_t'.

In the comparision with NULL that array is converted to a pointer to its first
element, of type 'char*'.

That pointer to the first element of some array will never be NULL, except by
accident somewhere after invoking Undefined Behavior.

Hence you get an infinite loop, with Undefined Behavior as soon you have
incremented your 'authors' pointer for the third time (at which time you're
accessing a non-existent array).


{
printf(" %s ", authors);

As a beginner it's a good idea to use more type safe 'std::cout'.

authors++;

It's also a good idea to get into the habit of preferentially using prefix
increment, not postfix.

}

This goes into an infinite loop. Not sure why.

See above.

Can someone please tell me the best way to return a pointer to an array of
char

Use std::string and std::vector.

and how to iterate through the array without using vector (or another
STL container)?

Why?
 
J

John Harrison

Because *authors never equals NULL presumably. Why exactly are you
expecting it to?

Not presumably, as Alf pointed out *authors will never ever equal NULL.

You confused me and yourself with your C style code.

Unless you have been absolutely forbidden to do so switch to a vector of
strings. Much easier, that is a good thing.

john
 
R

Robbie Hatley

techie said:
I'm creating a class BookType that will store information about books. Each
book type can have up to 4 authors.
I defined a new type for an array of char:
typedef char array4_t[25];

typedef doesn't make new types; it just renames types.
This will hold 25 characaters
I declared a 2 dimensional array of char in BookType:
char m_authors[4][25];
I could have used vector but this just a practical exercise.
I have a SetAuthors function which sets the authors which accepts a pointer
to a pointer toi char (char**). It works fine.
I also have a function GetAuthors that returns a pointer to array4_t:

array4_t* BookType::GetAuthors()
{
return m_authors;
}

That's not very safe, easy, or "practical" as you put it.
"Practical" would mean using a list of strings (or other
safe, easy technique). (See below for a "practial" solution.)
In my test program I want to loop through the array of strings and print the
authors. I've done this but it doesn't work well:

array4_t* authors = books->GetAuthors();
while (*authors != NULL)
{
printf(" %s ", authors);
authors++;
}
This goes into an infinite loop. Not sure why.

Can someone please tell me the best way to return a pointer to an array of
char and how to iterate through the array without using vector (or another
STL container)?


I could, but I won't. Don't do that! Why make a headache for yourself?
Instead, do something like this:

#include <iostream>
#include <list>
#include <string>

typedef std::list<std::string> LS;
typedef std::list<std::string>::iterator LSI;

class BookType
{
public:

void AddAuthor(std::string const & A)
{
ListOfAuthors.push_back(A);
}

LS GetAuthors ()
{
return ListOfAuthors;
}

private:
std::list<std::string> ListOfAuthors;
};

int main()
{
BookType CookBooks;
CookBooks.AddAuthor("Child, Julia");
CookBooks.AddAuthor("Puck, Wolfgang");
CookBooks.AddAuthor("Pepin, Jacques");
LS CBAuthors = CookBooks.GetAuthors();
LSI i;
for ( i = CBAuthors.begin() ; i != CBAuthors.end() ; ++i )
{
std::cout << (*i) << std::endl;
}
return 0;
}


Cheers,
Robbie Hatley
Tustin, CA, USA
email: lonewolfintj at pacbell dot net
web: home dot pacbell dot net slant earnur slant
 
T

techie

Alf P. Steinbach said:
array4_t* authors = books->GetAuthors();
while (*authors != NULL)


'authors' is of type 'array4_t*'.

'*authors' is of type 'array4_t'.

In the comparision with NULL that array is converted to a pointer to its first
element, of type 'char*'.

That pointer to the first element of some array will never be NULL, except by
accident somewhere after invoking Undefined Behavior.

Hence you get an infinite loop, with Undefined Behavior as soon you have
incremented your 'authors' pointer for the third time (at which time you're
accessing a non-existent array).


Correct! That's why I get an infinite loop.

I changed my program to do this and now I don't get an infinite loop:

array25_t* authors = books->GetAuthors();
char* author = NULL;
int x = 0;
while (*(author = authors[x]) != '\0')
{
printf(" %s ", authors);
x++;
}


Using arrays like this you have to remember to put a terminating NULL or
store the number of elements in the array. I think using vector or list is
far more elegant.

Thanks everyone for your help.
 
B

Ben Pope

Robbie said:
I'm creating a class BookType that will store information about books. Each
book type can have up to 4 authors.
I defined a new type for an array of char:
typedef char array4_t[25];


typedef doesn't make new types; it just renames types.

....creates an alias for the type.

Ben
 
A

Alf P. Steinbach

* techie:
I changed my program to do this and now I don't get an infinite loop:

array25_t* authors = books->GetAuthors();
char* author = NULL;
int x = 0;
while (*(author = authors[x]) != '\0')
{
printf(" %s ", authors);
x++;
}


Did you notice that this loop prints the _same_ author again and again?
 
R

Robbie Hatley

I said:
typedef doesn't make new types; it just renames types.

"Ben Pope" replied:
...creates an alias for the type.

Hmmm, yes, that is a better way to phrase it. More clear
than the way I said it.


Cheers,
Robbie Hatley
Tustin, CA, USA
email: lonewolfintj at pacbell dot net
web: home dot pacbell dot net slant earnur slant
 

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

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top