I am currently attempting to teach myself C++ so I don't have the benefit of a prof or TA. The question at the end of the chapter that I'm working on wants me to create an array of structures and to initialize the array of structures using the new function. So essentially, I have to create an array of structures and use a pointer to point to it, but here is my question. How do you reference an element of the array. The book only gives examples where it does something like this

pt->structureElmeent

or

(*pt).structureElement


When I try to do pt[2]->structureElement

or

(*pt[2]).structureElement

I get an error. I can post my actual code, but I'm more interested in learning the actual syntax rules for this. Any help would be greatly appreciated.

Let's say you have a structure definition struct { int x; } a[10]; . For the sake of indexing, a is a pointer, so you can get to an element through either the a[<index>] or *(a + <index>) methods. At that point you have a structure object, so the . operator is used:

a[2].x; // This works
(*(a + 2)).x; // This works too

You can do indexing to get the address as well, in which case you'd have a pointer to a structure object:

(&a[2])->x; // This works
(a + 2)->x; // So does this

In your tests you were digging too deep as far as levels of indirection, assuming this is an array of struct objects rather than an array of pointers to struct objects:

>pt[2]->structureElement
p[2] is presumably a structure object, not a pointer to a structure unless your struct looks like struct { T structureElement; } *pt[N]; . So instead of using the arrow operator, which only works on pointers to structures, you use the dot operator:

pt[2].structureElement

>(*pt[2]).structureElement
Once again, pt[2] is already a structure object, not a pointer, so you can't dereference it.

Edited 5 Years Ago by Narue: n/a

The array-index operator is actually a type of de-referencing operator, like * or ->, that's specific to arrays. The operator has lower operator precedence than the other de-referencing operators, so it behaves strangely in these situations.

You need to get to the element before you try to dereference it. Have you tried (pt[2])->element ?

Otherwise, have you done any "pointer arithmetic" yet? The array index operator is actually syntactic sugar. Pointer arithmetic is the underlying behavior that makes the array index operator work. That will probably be your easiest way to do it.

customType *myCustomObjs[2] = {new customType, new customType};

*(myCustomObjs + 1) -> structElement;

EDIT:
Where'd Narue come from???

@Narue:
The OP needs to use the new operator...
"The question at the end of the chapter that I'm working on wants me to create an array of structures and to initialize the array of structures using the new function." (emphasis added)
Maybe I'm mistaken, but doesn't this imply that the array should be an array of pointers.

Edited 5 Years Ago by Fbody: n/a

Thanks for the responses. After attempting to compile the code again, I think that the problem actually lies in how I'm initializing each structure. Here is the code in it's entirety.

//candybar.cpp -- Candy Bar structure
#include <iostream>

struct candybar { char name[20]; float weight; int calories;};

int main()
{
	using namespace std;
	candybar *snack = new candybar [3];
	snack[0] = {"Mocha Monch", 2.3, 350};
	snack[1]= {"Milky Way", 2.2, 360};
	snack[2]= {"Twix", 2.0, 340};
	
	//displaying the information for first structure)
	cout << "The candy bar "<< snack[0]->name << " weighs " << snack[0]->weight;
	cout << " and it has " << snack[0]->calories << " calories. \n";

	//displaying the information for second structure
	cout << "The candy bar " <<snack[1]->name << " weighs " << snack[1]->weight;
	cout << " and it has " <<snack[1]->calories << " calories. \n";

	//displaying the information for third structure
	cout << "The candy bar " <<snack[2]->name << " weighs " << snack[2]->weight;
	cout << " and it has " << snack[2]->calories << " calories. \n";

	cin.get();
	delete [] snack;
	return 0;
}

Any thoughts?

The new operator returns a pointer (address) of the object(s) that memory has been allocated for. That pointer must be stored someplace in order for it to be gain access to the memory. When the [] operator is used to allocate memory for a group of objects then memory will be consecutive and the address that is returned will be the address of the first object in the group of objects. It turns out that the name of an array is a pointer to the first element in the array so it turns out that the pointer to which the new operator an address to will be able to act like an array, even though technically it isn't an array. That means you can use the [] operator on the object just like you would normally.

candybar *snack = new candybar [3];//allocate memory for three candybar objects, or, eqivalently, declare memory for an array of 3 candybar objects and call the array snack.

strcpy(snack[0].name, "Snickers"); //place Snickers in the name field of the first element in snack.

Once the memory has been allocated using the new or new [] operators you can't initialize it with this syntax:

snack[0] = {"Mocha Monch", 2.3, 350};

You have to assign each field separately and since you can't assign C style strings one to the other, you must use strcpy().

Edited 5 Years Ago by Lerner: n/a

Comments
Thank you so much. I would not have figured that out on my own.
This question has already been answered. Start a new discussion instead.