425,501 Members | 1,660 Online Need help? Post your question and get tips & solutions from a community of 425,501 IT Pros & Developers. It's quick & easy.

# How To Make Vector = Pointer

 P: n/a Here's what I have: void miniVector::insertOrder(miniVector& v,const T& item) { int i, j; T target; vSize += 1; T newVector; newVector=new T[vSize]; for(i = 0; i < vSize-1; i++) newVector[i] = v[i]; newVector[vSize] = item; v = newVector; } The problem is that the compiler won't let me set "v = newVector;". I get the following error: error: invalid conversion from 'int*' to 'int' What I'm trying to do is create a new vector that is one size larger than an existing vector in order to add an item. How can I make the existing vector equal to the new pointer? Thanks! Sep 15 '05 #1
10 Replies

 P: n/a see in context "Bob" wrote in message news:11*********************@g14g2000cwa.googlegro ups.com... Here's what I have: void miniVector::insertOrder(miniVector& v,const T& item) { int i, j; T target; vSize += 1; T newVector; newVector=new T[vSize]; ^^^^ you are trying to assing to an object of type T a pointer to an array of objects of type T try this instead: T* newVector = new T[vSize]; for(i = 0; i < vSize-1; i++) newVector[i] = v[i]; newVector[vSize] = item; v = newVector; ^^^^^^^^^^^^^^ hope that your miniVector has an assignment operator that accepts T* as rhs // you also forgot to delete[] newVector; } The problem is that the compiler won't let me set "v = newVector;". I get the following error: error: invalid conversion from 'int*' to 'int' What I'm trying to do is create a new vector that is one size larger than an existing vector in order to add an item. How can I make the existing vector equal to the new pointer? Thanks! I wouldn't do it the way you chose. Dan Sep 15 '05 #2

 P: n/a "Bob" wrote in message news:11*********************@g14g2000cwa.googlegro ups.com... Here's what I have: void miniVector::insertOrder(miniVector& v,const T& item) { int i, j; T target; vSize += 1; T newVector; newVector=new T[vSize]; for(i = 0; i < vSize-1; i++) newVector[i] = v[i]; newVector[vSize] = item; v = newVector; } Why don't you just do this? void miniVector::insertOrder(miniVector& v, const T& item) { v.push_back(item); } Sep 15 '05 #3

 P: n/a Thanks for the tip, but that still doesn't let me set "v = newVector;". Here's the modified code: template void miniVector::insertOrder(miniVector& v,const T& item) { int i, j; T target; vSize += 1; T* newVector = new T[vSize]; for(i = 0; i < vSize-1; i++) newVector[i] = v[i]; newVector[vSize] = item; v = newVector; delete [] newVector; } Did I type something wrong? Thanks! Sep 15 '05 #4

 P: n/a I could do that, but part of the specification is to use "new". From my limited knowledge of C++ I don't think "push_back" and "new" are designed to be used together. Yes? Thanks! Sep 15 '05 #5

 P: n/a "Bob" wrote in message news:11*********************@z14g2000cwz.googlegro ups.com... I could do that, but part of the specification is to use "new". From my limited knowledge of C++ I don't think "push_back" and "new" are designed to be used together. Yes? "new" and "vector" aren't designed to be used together. In other words, unless you've misunderstood the specification, you may well be out of luck. Sep 15 '05 #6

 P: n/a Bob wrote: Thanks for the tip, but that still doesn't let me set "v = newVector;". Here's the modified code: template void miniVector::insertOrder(miniVector& v,const T& item) { int i, j; T target; vSize += 1; T* newVector = new T[vSize]; for(i = 0; i < vSize-1; i++) newVector[i] = v[i]; newVector[vSize] = item; v = newVector; Why would this assignment make sense? The type of v is miniVector& and the type of newVector is T*. I can sense a problem right here. delete [] newVector; Either you are freeing memory used by v or you expect the assignment above to magically do some copying for you. Well, it does not really have a chance. Even if you had overloaded miniVector::operator= ( T* t_ptr ) and miniVector::operator= ( T t_arr[] ) to do some copying, you would find it impossible to tell the length of an array. So there is no way of telling when to stop the copying. } Did I type something wrong? Thanks! May I ask, why you are trying to re-invent the wheel. What kind of advantage does miniVector offer compared to std::vector, which a) would be already available to you, b) takes care of all the memory management for you, and c) has nice member functions such as push_back(). Best Kai-Uwe Bux Sep 15 '05 #7

 P: n/a The type mismatch makes sense... I changed T* newVector = new T[vSize]; to miniVector *newVector=new miniVector[vSize]; Yeah, I thought "v = newVector" would magically do what I wanted. I now take it doesn't work that way... The reinvention of the wheel is a study of, "this is how you could approach the task, then you'll learn the standard, more acceptable approach later." I'm sure there are better ways to accomplish the goal, but here's my specification: // Begin "Use the 'new' operation to implement the following algorithm: // v is in increasing order // v <= v <= v <= ... <= v[v.size()-1] // insert item into v so that v remains in increasing order template void insertOrder(miniVector& v, const T& item); // End So, what I'm doing is passing a vector "v" to "insertOrder". I was under the impression that I had to create a "new" vector one size larger, do a one for one transfer from "v" to "newVector". This would leave the last "cell" of "newVector" not filled so I could put "item" in "newVector[v.size]", then sort the little bugger. Since "newVector" is local to "insertOrder" I need someway to make "newVector" equal "v" so the rest of the program can "see" the new item. What do you think? Is my limited knowledge of C++ barking up the wrong tree? Thanks! Sep 15 '05 #8

 P: n/a Bob wrote: The type mismatch makes sense... I changed T* newVector = new T[vSize]; to miniVector *newVector=new miniVector[vSize]; Now, this will create a raw array of vSize miniVector-objects, and that is most definitely not what you want. Yeah, I thought "v = newVector" would magically do what I wanted. I now take it doesn't work that way... The reinvention of the wheel is a study of, "this is how you could approach the task, then you'll learn the standard, more acceptable approach later." I'm sure there are better ways to accomplish the goal, but here's my specification: // Begin "Use the 'new' operation to implement the following algorithm: // v is in increasing order // v <= v <= v <= ... <= v[v.size()-1] // insert item into v so that v remains in increasing order template void insertOrder(miniVector& v, const T& item); // End Could you post the code for this miniVector<> template? Clearly your teacher is thinking about using new() to work on a member-object of miniVector that happens to be of type T*. So, what I'm doing is passing a vector "v" to "insertOrder". I was under the impression that I had to create a "new" vector one size larger, do a one for one transfer from "v" to "newVector". This would leave the last "cell" of "newVector" not filled so I could put "item" in "newVector[v.size]", then sort the little bugger. That is a very good idea. However, you have to figure out how to properly create a miniVector of a specified size and initialize its data properly. Since "newVector" is local to "insertOrder" I need someway to make "newVector" equal "v" so the rest of the program can "see" the new item. In that case, miniVector most likely needs a copy constructor, assignment operator, and destructor if you want to do it properly. If you have access to the inner workings of miniVector, you could try to do it the dirty way; but I will not recommend that. Best Kai-Uwe Bux Sep 15 '05 #9

 P: n/a miniVector is below... Since "new" is new to me, I thought I had to create a new vector. Is it possible to use "new" to create a new "cell" inside of a vector? Is that what you mean when you said, "... using new() to work on a member-object of miniVector that happens to be of type T*."? "new" seems to be an easy concept when using simple data types, but using "new" with vectors seems to be a bit more complicated... #ifndef MINI_VECTOR #define MINI_VECTOR #include "d_except.h" // include exception classes #include "d_sort2.h" // sort algorithms using namespace std; template class miniVector { public: miniVector(int size = 0); // constructor. // Postconditions: allocates array with size number of elements // and capacity. elements are initialized to T(), the default // value for type T miniVector(const miniVector& obj); // copy constructor // Postcondition: creates current vector as a copy of obj ~miniVector(); // destructor // Postcondition: the dynamic array is destroyed miniVector& operator= (const miniVector& rhs); // assignment operator. // Postcondition: current vector holds the same data // as rhs T& back(); // return the element at the rear of the vector. // Precondition: the vector is not empty. if vector // is empty, throws the underflowError exception const T& back() const; // const version used when miniVector object is a constant T& operator[] (int i); // provides general access to elements using an index. // Precondition: 0 <= i < vSize. if the index is out // of range, throws the indexRangeError exception const T& operator[] (int i) const; // const version used when miniVector object is a constant void push_back(const T& item); // insert item at the rear of the vector. // Postcondition: the vector size is increased by 1 void insert(int i, const T& item); // insert item at index i in the vector. // Precondition vector is not empty and 0 <= i <= vSize. // Precondition the vector size increases by 1 void erase(int i); // erase the item at index i in the vector. // Preconditions vector is not empty and 0 <= i < vSize. // Postcondition the vector size decreases by 1 void pop_back(); // remove element at the rear of the vector. // Precondition: vector is not empty. if the vector is // empty, throws the underflowError exception int size() const; // return current list size bool empty() const; // return true if vector is empty and false otherwise int capacity() const; // return the current capacity of the vector void insertOrder(miniVector& v,const T& item); private: int vCapacity; // amount of available space int vSize; // number of elements in the list T *vArr; // the dynamic array void reserve(int n, bool copy); // called by public functions only if n > vCapacity. expands // the vector capacity to n elements, copies the existing // elements to the new space if copy == true, and deletes // the old dynamic array. throws the memoryAllocationError // exception if memory allocation fails }; // set the capacity to n elements template void miniVector::reserve(int n, bool copy) { T *newArr; int i; // allocate a new dynamic array with n elements newArr = new T[n]; if (newArr == NULL) throw memoryAllocationError( "miniVector reserve(): memory allocation failure"); // if copy is true, copy elements from the old list to the new list if (copy) for(i = 0; i < vSize; i++) newArr[i] = vArr[i]; // delete original dynamic array. if vArr is NULL, the vector was // originally empty and there is no memory to delete if (vArr != NULL) delete [] vArr; // set vArr to the value newArr. update vCapacity vArr = newArr; vCapacity = n; } // constructor. initialize vSize and vCapacity. // allocate a dynamic array of vSize integers // and initialize the array with T() template miniVector::miniVector(int size): vSize(0), vCapacity(0), vArr(NULL) { int i; // if size is 0, vSize/vCapacity are 0 and vArr is NULL. // just return if (size == 0) return; // set capacity to size. since we are building the vector, // copy is false reserve(size, false); // assign size to vSize vSize = size; // copy T() into each vector element for (i=0;i < vSize;i++) vArr[i] = T(); } // copy constructor. make the current object a copy of obj. // for starters, use initialization list to create an empty // vector template miniVector::miniVector (const miniVector& obj): vSize(0), vCapacity(0), vArr(NULL) { int i; // if size is 0, vSize/vCapacity are 0 and vArr is NULL. // just return if (obj.vSize == 0) return; // set capacity to obj.vSize. since we are building the vector, // copy is false reserve(obj.vSize, false); // assign size to obj.vSize vSize = obj.vSize; // copy items from the obj.vArr to the newly allocated array for (i = 0; i < vSize; i++) vArr[i] = obj.vArr[i]; } // destructor. deallocate the dynamic array template miniVector::~miniVector() { if (vArr != NULL) // de-allocate memory for the array delete [] vArr; } // replace existing object (left-hand operand) by // rhs (right-hand operand) template miniVector& miniVector::operator= (const miniVector& rhs) { int i; // check vCapacity to see if a new array must be allocated if (vCapacity < rhs.vSize) // make capacity of current object the size of rhs. don't // do a copy, since we will replace the old values reserve(rhs.vSize, false); // assign current object to have same size as rhs vSize = rhs.vSize; // copy items from rhs.vArr to vArr for (i = 0; i < vSize; i++) vArr[i] = rhs.vArr[i]; return *this; } // check vSize and throw an underflowError exception if the // value is 0; otherwise return the element vArr[vSize-1] template T& miniVector::back() { if (vSize == 0) throw underflowError( "miniVector back(): vector empty"); return vArr[vSize-1]; } template const T& miniVector::back() const { if (vSize == 0) throw underflowError( "miniVector back(): vector empty"); return vArr[vSize-1]; } // provides general access to array elements template T& miniVector::operator[] (int i) { if (i < 0 || i >= vSize) throw indexRangeError( "miniVector: index range error", i, vSize); return vArr[i]; } // provides general access to array elements. constant version template const T& miniVector::operator[] (int i) const { if (i < 0 || i >= vSize) throw indexRangeError( "miniVector: index range error", i, vSize); return vArr[i]; } // insure that list has sufficient capacity, // add the new item to the list, and increment vSize template void miniVector::push_back(const T& item) { // if space is full, allocate more capacity if (vSize == vCapacity) { if (vCapacity == 0) // if capacity is 0, set capacity to 1. // set copy to false because there are // no existing elements reserve(1,false); else // double the capacity reserve(2 * vCapacity, true); } // add item to the list, update vSize vArr[vSize] = item; vSize++; } template void miniVector::insert(int index, const T& item) //void miniVector::xinsert(const T& item) { int xcell,temp; // if space is full, allocate more capacity if (vSize == vCapacity) { if (vCapacity == 0) // if capacity is 0, set capacity to 1. // set copy to false because there are // no existing elements reserve(1,false); else // double the capacity reserve(2 * vCapacity, true); } cout << "Index: " << index << endl; for(xcell=vSize-1;xcell>index-1;xcell--) { temp=vArr[xcell]; vArr[xcell+1]=temp; } vArr[index]=item; // update vSize vSize++; } template void miniVector::erase(int i) { int temp; for(int cell=i;cell void miniVector::pop_back() { if (vSize == 0) throw underflowError( "miniVector pop_back(): vector is empty"); vSize--; } template int miniVector::size() const { return vSize; } template bool miniVector::empty() const { return vSize == 0; } template int miniVector:: capacity() const { return vCapacity; } template void miniVector::insertOrder(miniVector& v,const T& item) { int i, j, n = v.size(); T target; // v.insert(0,item); vSize += 1; // T newVector; /// newVector=new T[vSize]; // T* newVector = new T[vSize]; //// miniVector newVector = new miniVector[vSize]; miniVector *newVector=new miniVector[vSize]; // Put memory allocation error stuff here. //// for(i = 0; i < vSize-1; i++) //// newVector[i] = v[i]; // newVector[i] = item; //// newVector[vSize] = item; delete [] newVector; // delete [] v; v = newVector; vSize += 1; miniVector *newVector=new miniVector[vSize]; /* for (i = 1; i < vSize; i++) { j = i; target = newVector[i]; while (j > 0 && target < newVector[j-1]) { newVector[j] = newVector[j-1]; j--; } newVector[j] = target; } */ // miniVector v2; } #endif // MINI_VECTOR Sep 15 '05 #10

 P: n/a Bob wrote: miniVector is below... Ok, great! This helps. Since "new" is new to me, I thought I had to create a new vector. This appears to be the only way. [details below] Is it possible to use "new" to create a new "cell" inside of a vector? No. [details below] Is that what you mean when you said, "... using new() to work on a member-object of miniVector that happens to be of type T*."? No. I did not know the design of miniVector. Details: ======== Let me quote the interface for miniVector: template class miniVector { public: miniVector(int size = 0); miniVector(const miniVector& obj); ~miniVector(); miniVector& operator= (const miniVector& rhs); T& back(); const T& back() const; T& operator[] (int i); const T& operator[] (int i) const; void push_back(const T& item); void insert(int i, const T& item); void erase(int i); void pop_back(); int size() const; bool empty() const; int capacity() const; void insertOrder(miniVector& v,const T& item); private: int vCapacity; // amount of available space int vSize; // number of elements in the list T *vArr; // the dynamic array void reserve(int n, bool copy); }; As you can see, there is a private member vArr of type T*. That is where miniVector actually stores the data. The other two variables keep track of the size of the array and the length of the portion currently used. Since these members are *private*, they are inaccessible to you. All communications with a miniVector go through the public member functions. Now, as you can see, there is no "new" among them. This leaves a few options: a) complain about your specs: Clearly it makes way more sense to just use the push_back() member function to add an element (and then sort the critter as you already intend). b) Do a complete work-around. I am thinking of something like this: template < typename T > void insertOrder(miniVector& v, const T& item); // create a temporary raw-array: unsigned long newLength = v.size() + 1; T* newArray = new T [ newLength ]; // copy all data in v to newArray that are < item // insert item behind these data // copy the rest of the v-data into newArray. // copy newArray back into v: v.clear(); for ( unsigned long i = 0; i < newLength; ++ i ) { v.push_back( newArray[i] ); } // ditch the temporary raw array delete[] newArray; } c) Ask whether you can make insertOrder() a *friend* of miniVector. In this case, you could access the private members of miniVector directly and do away with the stupid copying from (b). However, in this case, you would probably just call reserve() and not use new. Best Kai-Uwe Bux PS.: I think reserve() might not work as advertised: void reserve(int n, bool copy); // called by public functions only if n > vCapacity. expands // the vector capacity to n elements, copies the existing // elements to the new space if copy == true, and deletes // the old dynamic array. throws the memoryAllocationError // exception if memory allocation fails // set the capacity to n elements template void miniVector::reserve(int n, bool copy) { T *newArr; int i; // allocate a new dynamic array with n elements newArr = new T[n]; if (newArr == NULL) IIRC, new will not return 0 in case you are running out of memory. Instead it will throw a bad_alloc exception. throw memoryAllocationError( "miniVector reserve(): memory allocation failure"); // if copy is true, copy elements from the old list to the new list if (copy) for(i = 0; i < vSize; i++) newArr[i] = vArr[i]; // delete original dynamic array. if vArr is NULL, the vector was // originally empty and there is no memory to delete if (vArr != NULL) delete [] vArr; // set vArr to the value newArr. update vCapacity vArr = newArr; vCapacity = n; } Sep 15 '05 #11

### This discussion thread is closed

Replies have been disabled for this discussion. 