squashed.bugaboo
squashed.bugaboo

Reputation: 1356

C++ passing pointer to vector element instead of array pointer

I think the following code snippet is perfectly legal (it builds anyway on MS Visual Studio 2008, C++).

I use it to link to a 3rd party library. But I think because I am passing a pointer to a vector element instead of a regular pointer that the 3rd party library function expects, I get a run-time error

Invalid parameter detected by C-runtime library

What am I doing wrong here?

std::vector<int> vec_ints(27,0);
std::vector<double> vec_doub(27, 0.);
for(int i = 0; i < n; ++i) {
   //-Based on my understanding when i >=27, STL vectors automatically reallocate additional space (twice).
   vec_ints[i] = ...;
   vec_doub[i] = ...;     
}
const int* int_ptr = &vec_ints[0];
const double* doub_ptr = &vec_doub[0];
//-Func is the 3rd party library function that expects a const int* and const double* in the last 2 arguments.
func(...,...,int_ptr,doub_ptr);

But running this after building on MS Visual Studio 2008 (Windows Vista), leads to run-time error as mentioned above, viz.,

Invalid parameter detected by C runtime library

Haven't tested this on Linux yet and I sure would like to avoid copying the contents of the vector into an array just for this. Any ideas what is going on?

Further edit to confirm usage of Nick and Chris' recommendation and to continue discussion with Vlad et al; here's a code snippet:

#include <iostream>
#include <vector>

int main() {
   for(int i=2; i<6; ++i) {
      int isq = i*i;
      std::vector<int> v;
      v.reserve(4);
      for(int j=0; j<isq; ++j) {
         v.push_back(j);
      }
      std::cout << "Vector v: size = " << v.size() << " capacity = " << v.capacity() 
                << "\n";
      std::cout << "Elements: \n";
      for(int k=0; k<v.size(); ++k) {
         std::cout << v.at(k) << "  ";
      }
      std::cout << "\n\n";
   }
   return 0;
}

Gives output:

Vector v: size = 4 capacity = 4
Elements: 
0  1  2  3  

Vector v: size = 9 capacity = 16
Elements: 
0  1  2  3  4  5  6  7  8  

Vector v: size = 16 capacity = 16
Elements: 
0  1  2  3  4  5  6  7  8  9  10  11  12  13  14  15  

Vector v: size = 25 capacity = 32
Elements: 
0  1  2  3  4  5  6  7  8  9  10  11  12  13  14  15  16  17  18  19  20  21  
22  23  24

So atleast for the usage in this context, where no explicit resize is used, it seems to work as intended/expected.

Upvotes: 2

Views: 2443

Answers (3)

Aaron McDaid
Aaron McDaid

Reputation: 27133

Why not just create the vectors with the correct size to begin with? Like so:

std::vector<int> vec_ints(n,0);
std::vector<double> vec_doub(n, 0.);

Upvotes: 1

Nick Strupat
Nick Strupat

Reputation: 5063

std::vector<T> expands if you are adding elements using std::vector<T>::push_back(T &), std::vector<T>::insert(iterator, T &) (thanks K-ballo) or explicitly calling std::vector<T>::resize(size_t). Otherwise, it doesn't expand.

std::vector<int> vec_ints;
vec_ints.reserve(27);
std::vector<double> vec_doub;
vec_doub.reserve(27);
for(int i = 0; i < n; ++i) {
    vec_ints.push_back(...);
    vec_doub.push_back(...);    
}
const int* int_ptr = &vec_ints[0];
const double* doub_ptr = &vec_doub[0];
func(...,...,int_ptr,doub_ptr);

You want something like that

Upvotes: 3

Vlad
Vlad

Reputation: 35594

No, vector doesn't expand automatically. You need to expand it yourself:

if (n > 27)
    vec_ints.resize(n, 0);

etc.

Upvotes: 3

Related Questions