Pointer to pointer

I started reading simultaneously Mark A. Weiss' C++ for Java Programmers and Vaughan Young's Programming a Multiplayer FPS in DirectX. In the last I encountered a few peculiarities not mentioned in my books which don't make sense for me.

The next code is part of a LinkedList (in both directions) template class (template< class Type > class LinkedList. The LinkedList uses Element pointers to an Element which contains pointers to data (Type), prev (Element), next (Element). I don't understand what the idea is of calling the remove method with a pointer to a pointer instead of just a pointer (*element)?

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
31
32
33
34
35
  //-------------------------------------------------------------------------
  // Removes the given element from the linked list and destroys its data.
  //-------------------------------------------------------------------------
	void Remove( Type **element )
	{
		m_temp = m_first;
		while( m_temp != NULL )
		{
			if( m_temp->data == *element )
			{
				if( m_temp == m_first )
				{
					m_first = m_first->next;
					if( m_first )
						m_first->prev = NULL;
				}
				if( m_temp == m_last )
				{
					m_last = m_last->prev;
					if( m_last )
						m_last->next = NULL;
				}

				SAFE_DELETE( m_temp );

				*element = NULL;

				m_totalElements--;

				return;
			}

			m_temp = m_temp->next;
		}
	}


Second, a constructor accepts a pointer to a structure. The class has a member variable (m_setup) pointing to such a structure. Wouldn't it be more efficient to just copy the pointer instead of creating a new object on the heap with the same properties and storing a pointer to that object?

1
2
3
4
5
6
7
Engine::Engine( EngineSetup *setup )
{
// If no setup structure was passed in, then create a default one.
// Otehrwise, make a copy of the passed in structure.
	m_setup = new EngineSetup;
	if( setup != NULL )
		memcpy( m_setup, setup, sizeof( EngineSetup ) );


In advance, thank you very much for your time and thoughts.

Matthias
The pointer to a pointer does seem pointless. Only one reason comes to mind as to why that is how it is. If the LinkedList allows duplicate data (as in data is equivalent to a node already in the list), then the pointer to a pointer would break ties. However in the example you gave the double pointer is unnecessary.

I think the reason the setup variable is copied is to remember the setup. Why would remembering the setup be useful for an Engine object? The setup variable could change theoretically and having a permanently remembered copy could be useful. I do notice a memory leak in that constructor though. If setup does not equal NULL, it overwrites the new EngineSetup from the previous line. That would leak memory overtime, since variables that are allocated with the new keyword need to be deallocated with the delete keyword.
I do notice a memory leak in that constructor though. If setup does not equal NULL, it overwrites the new EngineSetup from the previous line. That would leak memory overtime, since variables that are allocated with the new keyword need to be deallocated with the delete keyword.


I thought by applying the memcpy method as stated above would override the whole default EngineSetup object so that all of the default properties of the object are cleaned up and replaced. So the pointers got overriden which hide the objects pointed at causing the memory leak? Only *name is pointing to "Application" so this part is not cleaned up?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
struct EngineSetup
{
	HINSTANCE instance; // Application instance handle.
	char *name; // Name of the application.

	//-------------------------------------------------------------------------
	// The engine setup structure constructor.
	//-------------------------------------------------------------------------
	EngineSetup()
	{
		instance = NULL;
		name = "Application";
	}
};


Does this mean that I've to add a copy constructor? And can I add such a method to a structure?
Last edited on
Unless you know for a fact that you can because the documentation states so, NEVER use memcpy on a class or data structure. It doesn't do what you want. You should always use a copy constructor.
If memcpy works for objects why not for structures?

So the copy constructor:

1
2
3
4
5
6
7
8
9
EngineSetup::operator= ( const EngineSetup & rhs )
{
if( this != &rhs )
{
instance = rhs.instance;
name = rhs.name;
}
return *this;
}


Now it looks more like a class than a struct. Doesn't this break the whole idea of a structure?
Last edited on
matt77hias wrote:
If memcpy works for objects why not for structures?
It works for neither unless the object or structure is specifically designed for it to work.
Topic archived. No new replies allowed.