Confused about pointer arrays, getting garbage.

I've been trying to get this working. After I pass the *table, the first index has the correct values, but if I index beyond 0, I get garbage. It works fine in main with correct values. I've tried several ways but cannot figure out what I am doing wrong. I've included just some small snippets of code.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
Table::Table(int tblid, int mseats) : maxSeats(mseats) 
{
	tableId = tblid;
	status = IDLE;
	numPeople = 0;
}

Waiter::Waiter(string name, string TableList, Table *table)
{
	this->name = name;
	cout << table[0].getMaxSeats() << endl;
	cout << table[1].getMaxSeats() << endl; // GARBAGE!

}

void main()
{
	const int MAX_TABLES = 100; // Maximum number of tables.
	const int MAX_WAITERS = 100; // Maximum number of waiters.

	Table *tables[MAX_TABLES]; // Array of pointers to table objects.

	tables[0] = new Table(100, 4);
	tables[1] = new Table(101, 8);

	Waiter *waiters[MAX_WAITERS]; // Array of pointers to waiter objects.

	waiters[0] = new Waiter("Steve", "1,2,3,4", *tables);
	waiters[1] = new Waiter("Bob", "5,6,7,8", *tables);
}
The confusion is between array of pointers and pointer to an array.

tables is an array of pointers. When you try to dereference it by *tables, you are in effect passing tables[0] as the argument.

If you want to pass the entire array, then just try:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Waiter::Waiter(string name, string TableList, Table *table[] ) // array of pointers
{
	this->name = name;
	cout << table[0].getMaxSeats() << endl;
	cout << table[1].getMaxSeats() << endl; // GARBAGE!

}

void main()
{
	const int MAX_TABLES = 100; // Maximum number of tables.
	const int MAX_WAITERS = 100; // Maximum number of waiters.

	Table *tables[MAX_TABLES]; // Array of pointers to table objects.

	tables[0] = new Table(100, 4);
	tables[1] = new Table(101, 8);

	Waiter *waiters[MAX_WAITERS]; // Array of pointers to waiter objects.

	waiters[0] = new Waiter("Steve", "1,2,3,4", tables);
	waiters[1] = new Waiter("Bob", "5,6,7,8", tables);
}
My reply is a bit late, but I decided to post it anyway.

First of all, if you're coming from Java, be advised that in C++ every new must have a corresponding delete, otherwise a memory leak occurs.*

* unless you're using smart pointers such as std::unique_ptr.

In the code below, why are you dereferencing tables?
By doing this you effectively pass the first element of the tables array instead of the entire array.

1
2
	waiters[0] = new Waiter("Steve", "1,2,3,4", *tables);
	waiters[1] = new Waiter("Bob", "5,6,7,8", *tables);


This is probably what you wanted to do:

1
2
	waiters[0] = new Waiter("Steve", "1,2,3,4", tables);
	waiters[1] = new Waiter("Bob", "5,6,7,8", tables);


And then your Waiter constructor must be changed accordingly.

1
2
3
4
5
6
7
8
9
10
11
Waiter::Waiter(string name, string TableList, Table *tables[]): name(name)
{
	// this->name = name; // can still use initialization lists, as seen above

	// use -> for accessing member data/functions from a pointer
	// p->func() same as (*p).func()

	cout << tables[0]->getMaxSeats() << '\n'; // don't overuse endl, it flushes the stream
	cout << tables[1]->getMaxSeats() << endl;

}


Adding the square brackets for *tables[] is just syntactic sugar, the code would behave the same if we wrote **tables instead.

This is because in C and C++, arrays decay to pointers, that is when you use an array's name, it becomes a pointer to the first element in the array and not the array itself.

A final observation, you are overusing pointers.
My suggestion is to simply use containers, and smart pointers if you absolutely must.

http://www.cplusplus.com/reference/stl/
http://www.cplusplus.com/reference/memory/unique_ptr/
Last edited on
Topic archived. No new replies allowed.