I'm having problems using a void pointer to iterate through a SimpleVector template I got from a book...

This is basically what I'm trying to do
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
36
37
#include <iostream>
#include "SimpleVector.h"

void* thisReturnsVoidPointer(SimpleVector<int> theVector);

int main()
{
	SimpleVector<int> theVector(3);

	void* theVectorVoidPtr = thisReturnsVoidPointer(theVector);
	
	for (int i = 0; i < 3; i++)
	{
		theVector[i] = static_cast<SimpleVector<int>*>(theVectorVoidPtr)->getElementAt(i);
	}

	for (int i = 0; i < 3; i++)
	{
		cout << theVector[i];
	}

	cin.get();
}

void* thisReturnsVoidPointer(SimpleVector<int> theVector)
{
	void* theVectorVoidPtr;
	
	for (int i = 0; i < 3; i++)
	{
		theVector[i] = i+1;
	}

	theVectorVoidPtr = &theVector;

	return theVectorVoidPtr;
}


I want to copy the array that the void pointer is supposed to point to into a SimpleVector because I don't like the void pointer... it is confusing. But I get a subscript error, which is coming from this part of the SimpleVector template... How can I make the above code work?

1
2
3
4
5
6
7
template <class T>
T SimpleVector<T>::getElementAt(int sub)
{
   if (sub < 0 || sub >= arraySize)
      subError();
   return aptr[sub];
}




This is the template I'm using
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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
// SimpleVector class template
#ifndef SIMPLEVECTOR_H
#define SIMPLEVECTOR_H
#include <iostream>
#include <new>       // Needed for bad_alloc exception
#include <cstdlib>   // Needed for the exit function
using namespace std;

template <class T>
class SimpleVector
{
private:
   T *aptr;          // To point to the allocated array
   int arraySize;    // Number of elements in the array
   void memError();  // Handles memory allocation errors
   void subError();  // Handles subscripts out of range

   //int back; // holds index of last array element



public:
   // Default constructor
   SimpleVector()
      { aptr = 0; arraySize = 0;}
      
   // Constructor declaration
   SimpleVector(int);
   
   // Copy constructor declaration
   SimpleVector(const SimpleVector &);
   
   // Destructor declaration
   ~SimpleVector();
   
   // Accessor to return the array size
   int size() const
      { return arraySize; }

   // Accessor to return a specific element
   T getElementAt(int position);

   // Overloaded [] operator declaration
   T &operator[](const int &);

   //calling paramater dataItem instead of value (like in the stl vector) so that 
   //in comments I won't have to say weird things like "the value of value"

   
   T* push_back(T dataItem);
   
   
};

//***********************************************************
// Constructor for SimpleVector class. Sets the size of the *
// array and allocates memory for it.                       *
//***********************************************************

template <class T>
SimpleVector<T>::SimpleVector(int s)
{
   arraySize = s;
   // Allocate memory for the array.
   try
   {
      aptr = new T [s];
   }
   catch (bad_alloc)
   {
      memError();
   }

   // Initialize the array.
   //This code is causing problems with making a vector of acounts
   //because an account object can't be set to zero
   //for (int count = 0; count < arraySize; count++)
   //   *(aptr + count) = 0;


}

//*******************************************
// Copy Constructor for SimpleVector class. *
//*******************************************

template <class T>
SimpleVector<T>::SimpleVector(const SimpleVector &obj)
{
   // Copy the array size.
   arraySize = obj.arraySize;
   
   // Allocate memory for the array.
   aptr = new T [arraySize];
   if (aptr == 0)
      memError();
      
   // Copy the elements of obj's array.
   for(int count = 0; count < arraySize; count++)
      *(aptr + count) = *(obj.aptr + count);
}

//**************************************
// Destructor for SimpleVector class.  *
//**************************************

template <class T>
SimpleVector<T>::~SimpleVector()
{
   if (arraySize > 0)
      delete [] aptr;
}

//*******************************************************
// memError function. Displays an error message and     *
// terminates the program when memory allocation fails. *
//*******************************************************

template <class T>
void SimpleVector<T>::memError()
{
   cout << "ERROR:Cannot allocate memory.\n";
   exit(EXIT_FAILURE);
}

//***********************************************************
// subError function. Displays an error message and         *
// terminates the program when a subscript is out of range. *
//***********************************************************

template <class T>
void SimpleVector<T>::subError()
{
   cout << "ERROR: Subscript out of range.\n";
   exit(EXIT_FAILURE);
}

//*******************************************************
// getElementAt function. The argument is a subscript.  *
// This function returns the value stored at the sub-   *
// cript in the array.                                  *
//*******************************************************

template <class T>
T SimpleVector<T>::getElementAt(int sub)
{
   if (sub < 0 || sub >= arraySize)
      subError();
   return aptr[sub];
}

//*******************************************************
// Overloaded [] operator. The argument is a subscript. *
// This function returns a reference to the element     *
// in the array indexed by the subscript.               *
//*******************************************************

template <class T>
T &SimpleVector<T>::operator[](const int &sub)
{
   if (sub < 0 || sub >= arraySize)
      subError();
   return aptr[sub];
}


template <class T>
T* SimpleVector<T>::push_back(T dataItem)
{
	int newArraySize;

	// Copy the array size and add 1 to hold the new element
	//new array size is one bigger than the size of original array
	newArraySize = this->arraySize + 1;

	T* newTempArrayPtr;
	
	// Allocate memory for the new array.
	newTempArrayPtr = new T [newArraySize];
	if (aptr == 0)
	{
		 memError();
	}

	//copy elements of original array to new temporary array
	for (int i = 0; i < arraySize; i++)
	{
		newTempArrayPtr[i] = aptr[i];
	}

	//set value in last index of newTempArrayPtr to be value of dataItem
	newTempArrayPtr[newArraySize - 1] = dataItem;

	//make aptr point to address of the array that newTempArrayPtr points to
	//(Tried to do this with function returning void but it doesn't work.)
	//*aptr = *newTempArrayPtr;

	//increment member variable arraySize so that it will contain the size of the new array
	arraySize++;

	aptr = new T [newArraySize];

	for (int i = 0; i < newArraySize; i++)
	{
		aptr[i] = newTempArrayPtr[i];
	}

	//delete the temporary pointer to the new array. it is not needed any more because 
	//aptr points to the new array now.
	//delete [] newTempArrayPtr;




	////the variable arraySize will contain the old array's size.
	////arraySize will be changed to the new array size near end of the
	////function

 //  //   // Copy the elements of obj's array
 //  //for(int count = 0; count < arraySize; count++)
 //  //   *(aptr + count) = *(obj.aptr + count);

 //  ////make arraySize 1 element bigger than it was before by changing it to newArraySize
 //  //arraySize = newArraySize;

 //  ////Then add the dataItem to the end
 //  //*(aptr + (arraySize - 1)) = dataItem;

	return aptr;
}


#endif  
Last edited on
You are returning a pointer to a copy of the vector you passed to the function, pass it by reference.
void* thisReturnsVoidPointer(SimpleVector<int>& theVector);
Last edited on
Oh thanks. I assumed since it was an array that it would be passed by reference automatically.
It's not an array but, in simple terms, an object that acts like an array.
I realized that in simplifying my problem into the above code... I didn't accurately represent the problem. I want to make size the SimpleVector dynamically by reading in the size from a file in the function. I still have the problem but I realized I can make my life easier by making a dynamic array in the function rather than a SimpleVector and then copying everything into the SimpleVector once I have returned the array. Then I wouldn't have to mess with this confusing void pointer stuff... Still. I am really curious about how I would do this with the void pointer. Is it even possible to do this? This is what I've been messing with but all I can do is get it to print out the lowest number the computer can hold 3 times. Why does it do that?

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
36
37
38
39
40
#include <iostream>
#include "SimpleVector.h"

void* thisReturnsVoidPointer();

int main()
{

	void* theVectorVoidPtr = thisReturnsVoidPointer();
	
	SimpleVector<int> copyOfTheVector(3);
	

	for (int i = 0; i < 3; i++)
	{
		copyOfTheVector.aptr[i] = *(static_cast<int*>(theVectorVoidPtr));
	}

	for (int i = 0; i < 3; i++)
	{
		cout << copyOfTheVector[i] << " ";
	}

	cin.get();
}

void* thisReturnsVoidPointer()
{
	SimpleVector<int> theVector(3);
	void* theVectorVoidPtr;
	
	for (int i = 0; i < 3; i++)
	{
		theVector[i] = i+1;
	}

	theVectorVoidPtr = &theVector;

	return theVectorVoidPtr;
}
Last edited on
Topic archived. No new replies allowed.