By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,159 Members | 1,000 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,159 IT Pros & Developers. It's quick & easy.

help with dynamic array structure.

P: n/a
I'm learning C++ from C++ Primer Plus 5th edition. I'm struggling at
the moment with declaring an array of three structures by using 'new' to
allocate memory. (this is one of the programming exercises at the end
of each chapter). My attempt is as per below. I get a compile error
indicating that -

"base operand of '->' has no pointer type 'candybar' "

// Q-09.cpp -- Question 9
#include <iostream>
struct candybar
{
//char brand[20];
std::string brand; //in this context - must use std::string
float weight;
int calories;
};
int main()
{
using namespace std;
candybar * snack = new candybar[3];

snack[0]->brand = "Mocha Munch"; // above error starts here
snack[0]->weight = 2.3;
snack[0]->calories = 350;

snack[1]->brand = "Crunchie";
snack[1]->weight = 1.9;
snack[1]->calories = 400;

snack[2]->brand = "Mars Bar";
snack[2]->weight = 4.5;
snack[2]->calories = 200;

cout << endl;
cout << "Snack brand : " << snack[0]->brand << endl;
cout << "Snack weight : " << snack[0]->weight << endl;
cout << "Snack calories : " << snack[0]->calories << endl;

cout << "Snack brand : " << snack[1]->brand << endl;
cout << "Snack weight : " << snack[1]->weight << endl;
cout << "Snack calories : " << snack[1]->calories << endl;

cout << "Snack brand : " << snack[2]->brand << endl;
cout << "Snack weight : " << snack[2]->weight << endl;
cout << "Snack calories : " << snack[2]->calories << endl;

delete snack;
return 0;
}

Any help would be appreciated, I really can't see why this shouldn't
work. I read the chapter umpteen times but I must be missing something.

Steve Taylor
Melbourne, Australia.
Jul 23 '05 #1
Share this Question
Share on Google+
14 Replies


P: n/a
"Steven Taylor" <ne******@superjacent.net> wrote in message
news:42***********************@news.optusnet.com.a u
I'm learning C++ from C++ Primer Plus 5th edition. I'm struggling at
the moment with declaring an array of three structures by using 'new'
to allocate memory. (this is one of the programming exercises at
the end of each chapter). My attempt is as per below. I get a
compile error indicating that -

"base operand of '->' has no pointer type 'candybar' "

// Q-09.cpp -- Question 9
#include <iostream>
struct candybar
{
//char brand[20];
std::string brand; //in this context - must use std::string
float weight;
int calories;
};
int main()
{
using namespace std;
candybar * snack = new candybar[3];

snack[0]->brand = "Mocha Munch"; // above error starts here
snack[0]->weight = 2.3;
snack[0]->calories = 350;

Replace all of the -> operators with the . operator.

snack is a pointer, but using the subscript operator dereferences the
pointer. Thus snack[0] is of type candybar, not pointer to candybar.
--
John Carson

Jul 23 '05 #2

P: n/a


John Carson wrote:
"Steven Taylor" <ne******@superjacent.net> wrote in message
news:42***********************@news.optusnet.com.a u
I'm learning C++ from C++ Primer Plus 5th edition. I'm struggling at
the moment with declaring an array of three structures by using 'new'
to allocate memory. (this is one of the programming exercises at
the end of each chapter). My attempt is as per below. I get a
compile error indicating that -

"base operand of '->' has no pointer type 'candybar' "

// Q-09.cpp -- Question 9
#include <iostream>
struct candybar
{
//char brand[20];
std::string brand; //in this context - must use std::string
float weight;
int calories;
};
int main()
{
using namespace std;
candybar * snack = new candybar[3];

snack[0]->brand = "Mocha Munch"; // above error starts here
snack[0]->weight = 2.3;
snack[0]->calories = 350;


Replace all of the -> operators with the . operator.

snack is a pointer, but using the subscript operator dereferences the
pointer. Thus snack[0] is of type candybar, not pointer to candybar.


Thanks for your hlep John, it certainly compiled ok.

Steve.
Jul 23 '05 #3

P: n/a
Steven Taylor wrote:

I'm learning C++ from C++ Primer Plus 5th edition. I'm struggling at
the moment with declaring an array of three structures by using 'new' to
allocate memory. (this is one of the programming exercises at the end
of each chapter). My attempt is as per below. I get a compile error
indicating that -

"base operand of '->' has no pointer type 'candybar' "

// Q-09.cpp -- Question 9
#include <iostream>
struct candybar
{
//char brand[20];
std::string brand; //in this context - must use std::string
float weight;
int calories;
};
int main()
{
using namespace std;
candybar * snack = new candybar[3];

snack[0]->brand = "Mocha Munch"; // above error starts here


Your problem is here.
It is the way array indexing is defined in C++

a[index] is equivalent to *(a_as_ptr+index)

where a_as_ptr denotes a pointer to the first element of the array.

What you wanted to write was:

snack pointer
snack+0 index offset of index 0 to that pointer
*(snack+0) object at the index offset to that pointer
(*(snack+0)).brand the brand component of the object at the index
offset to that pointer

Due to the way array indexing is defined you can replace parts of the last expression.

(*(snack+0)).brand is equivalent to

snack[0].brand

So in short:
Even if snack is a pointer, snack[0] is no longer of pointer type, but is already
the object in the array. Therefore you don't use ->, but simply access the component
directly with a '.' operation.

--
Karl Heinz Buchegger
kb******@gascad.at
Jul 23 '05 #4

P: n/a


Karl Heinz Buchegger wrote:
snip

Your problem is here.
It is the way array indexing is defined in C++

a[index] is equivalent to *(a_as_ptr+index)

where a_as_ptr denotes a pointer to the first element of the array.

What you wanted to write was:

snack pointer
snack+0 index offset of index 0 to that pointer
*(snack+0) object at the index offset to that pointer
(*(snack+0)).brand the brand component of the object at the index
offset to that pointer

Due to the way array indexing is defined you can replace parts of the last expression.

(*(snack+0)).brand is equivalent to

snack[0].brand

So in short:
Even if snack is a pointer, snack[0] is no longer of pointer type, but is already
the object in the array. Therefore you don't use ->, but simply access the component
directly with a '.' operation.

Thanks, much appreciated.

Steve Taylor
Jul 23 '05 #5

P: n/a

"John Carson" <jc****************@netspace.net.au> ????
news:42***********************@un-2park-reader-02.sydney.pipenetworks.com.au...
"Steven Taylor" <ne******@superjacent.net> wrote in message
news:42***********************@news.optusnet.com.a u
I'm learning C++ from C++ Primer Plus 5th edition. I'm struggling at
the moment with declaring an array of three structures by using 'new'
to allocate memory. (this is one of the programming exercises at
the end of each chapter). My attempt is as per below. I get a
compile error indicating that -

"base operand of '->' has no pointer type 'candybar' "

// Q-09.cpp -- Question 9
#include <iostream>
struct candybar
{
//char brand[20];
std::string brand; //in this context - must use std::string
float weight;
int calories;
};
int main()
{
using namespace std;
candybar * snack = new candybar[3];

snack[0]->brand = "Mocha Munch"; // above error starts here
snack[0]->weight = 2.3;
snack[0]->calories = 350;

Replace all of the -> operators with the . operator.

snack is a pointer, but using the subscript operator dereferences the
pointer. Thus snack[0] is of type candybar, not pointer to candybar.
--
John Carson

==================================================
This Programme has a litte problem.First using string class ,you must use
headfile <string>
The other hand,I suggest you'd better use form like string a (" ") to
initiate variable of string class.
Jul 23 '05 #6

P: n/a

"Karl Heinz Buchegger" <kb******@gascad.at> wrote in message > So in short:
Even if snack is a pointer, snack[0] is no longer of pointer type, but is
already
the object in the array. Therefore you don't use ->, but simply access the
component
directly with a '.' operation.


Really? Wow...that's just strange. I guess I've never used an array of
pointers like that, because I sure didn't know this. (I tend to use vectors
nowadays for most dynamic array uses.)

So, suppose I actually _need_ a pointer from that array. How do I get it?

Like this?

candybar* pBar = &(snack[i]); // Like this?

That sure seems odd.

Somehow, I thought I'd used this kind of notation before somewhere:

(snack[i])->name = "Snickers";

Would that work?

-Howard
Jul 23 '05 #7

P: n/a
"Howard" <al*****@hotmail.com> wrote in message
news:CN*******************@bgtnsc04-news.ops.worldnet.att.net
"Karl Heinz Buchegger" <kb******@gascad.at> wrote in message > So in
short:
Even if snack is a pointer, snack[0] is no longer of pointer type,
but is already
the object in the array. Therefore you don't use ->, but simply
access the component
directly with a '.' operation.

Really? Wow...that's just strange. I guess I've never used an array
of pointers like that, because I sure didn't know this. (I tend to
use vectors nowadays for most dynamic array uses.)


There is no array of pointers, just a pointer to an dynamically allocated
array. The pointer name functions just the same as the name of a statically
allocated array in terms of accessing elements of the array.
So, suppose I actually _need_ a pointer from that array. How do I
get it?
Like this?

candybar* pBar = &(snack[i]); // Like this?
snack is a pointer, as is snack + i, so you can write:

candybar* pBar = snack + i;
That sure seems odd.
Not to me. Using a subscript on a pointer is equivalent to dereferencing
the pointer. To make the point clear, consider:

int x = 1;
int *ptr = &x;

Then ptr[0] is the same as *ptr, i.e., it is equivalent to x.
Somehow, I thought I'd used this kind of notation before somewhere:

(snack[i])->name = "Snickers";

Would that work?


No.
--
John Carson

Jul 23 '05 #8

P: n/a

"John Carson" <jc****************@netspace.net.au> wrote in message
news:42***********************@un-2park-reader-02.sydney.pipenetworks.com.au...
"Howard" <al*****@hotmail.com> wrote in message
news:CN*******************@bgtnsc04-news.ops.worldnet.att.net
"Karl Heinz Buchegger" <kb******@gascad.at> wrote in message > So in
short:

There is no array of pointers, just a pointer to an dynamically allocated
array.

D'oh! I got confused. Somehow, I was thinking that he'd allocated an array
of pointers. But, that would have been:

candybar** snack = new (candybar*)[10];

My bad. I'll go slink off into a corner and hide my face now.

-Howard


Jul 23 '05 #9

P: n/a
On Fri, 01 Apr 2005 22:27:10 -0800, Steven Taylor
<ne******@superjacent.net> wrote:

Besides, what is mentioned, you have to use:
delete[] , when deallocating what was allocated using new objects[]

Regards
Benny Andersen
Jul 23 '05 #10

P: n/a
yinquan wrote:
snip

==================================================
This Programme has a litte problem.First using string class ,you must use
headfile <string>
The other hand,I suggest you'd better use form like string a (" ") to
initiate variable of string class.


I was/am a little confused about this as well. When changing the arrow
membership to dot membership form - as suggested by other posters, the
program compiled and ran as intended, without the "#include <string>"
preprocessor directive. I'm not sure why, as I thought the 'include'
file is required.

Steve Taylor

Jul 23 '05 #11

P: n/a
"Steven Taylor" <ne******@superjacent.net> wrote in message
news:42**********************@news.optusnet.com.au
yinquan wrote:
snip

==================================================
This Programme has a litte problem.First using string class ,you
must use headfile <string>
The other hand,I suggest you'd better use form like string a (" ")
to initiate variable of string class.


I was/am a little confused about this as well. When changing the
arrow membership to dot membership form - as suggested by other
posters, the program compiled and ran as intended, without the
"#include <string>" preprocessor directive. I'm not sure why, as I
thought the 'include' file is required.

Steve Taylor


Sometimes one header file will #include another header file, which in turn
may #include another, which may #include another... Apparently on your
system the iostream header #includes the string header, either directly or
indirectly. This is implementation dependent and shouldn't be relied on. So,
yes, you should #include the string header.
--
John Carson

Jul 23 '05 #12

P: n/a
Theoretically I think it should be, but a lot of compilers include
stuff by default without telling you. Whatever compiler you're using
may be doing the same thing.

As an alternative, <iostream> might be including <string> within it. I
don't know if this is allowed by the standard or not.

(This is OT, but speaking of the standard, do you guys think it's
useful to get? You can buy the PDF version for pretty cheap and I think
I could print it for free and plop it into a binder, but do you think
it's something that is of use beyond compiler and other language tool
development?)

Jul 23 '05 #13

P: n/a
Howard wrote:

"Karl Heinz Buchegger" <kb******@gascad.at> wrote in message > So in short:
Even if snack is a pointer, snack[0] is no longer of pointer type, but is
already
the object in the array. Therefore you don't use ->, but simply access the
component
directly with a '.' operation.


Really? Wow...that's just strange. I guess I've never used an array of
pointers like that,


Look closely.
The OP did not allocate an array of pointers.
He allocted an array of objects. Bu the did it in a dynamic
way und thus has a pointer to that array.
--
Karl Heinz Buchegger, GASCAD GmbH
Teichstrasse 2
A-4595 Waldneukirchen
Tel ++43/7258/7545-0 Fax ++43/7258/7545-99
email: kb******@gascad.at Web: www.gascad.com

Fuer sehr grosse Werte von 2 gilt: 2 + 2 = 5
Jul 23 '05 #14

P: n/a
Evan wrote:

Theoretically I think it should be, but a lot of compilers include
stuff by default without telling you. Whatever compiler you're using
may be doing the same thing.

As an alternative, <iostream> might be including <string> within it. I
don't know if this is allowed by the standard or not.

(This is OT, but speaking of the standard, do you guys think it's
useful to get? You can buy the PDF version for pretty cheap and I think
I could print it for free and plop it into a binder, but do you think
it's something that is of use beyond compiler and other language tool
development?)


Depends on what you seek.
If you are an ordinary programmer which needs some form of reference
then I would not suggest the reference. It is written very technically
and for a lot of thins you need to be a detective to figure out why
things are the way they are. There are better books out there
for the purpose of serving as a language reference.
But if you seek some literature to settle discussions about language issues
you will need the Standard.

--
Karl Heinz Buchegger
kb******@gascad.at
Jul 23 '05 #15

This discussion thread is closed

Replies have been disabled for this discussion.