C++ passing pointer to vector element instead of a

2019-07-24 06:22发布

问题:

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.

回答1:

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



回答2:

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

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

etc.



回答3:

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.);