Return base array from vector

Will an array be allocated, and if so, what is the workaround?

double * GetArrayFromVector( std::map<std::string, double> m, char ** names, int count )
{ 
    if(!names) return 0;

    std::vector<double> vec(m.size());
    for (int i=0; i<count; ++i)
    { 
       if(!names[i]) return 0;
       std::map<std::string, double>::iterator iter=m.find(name[i]);
       if(iter!=m.end())
          vec.push_back(iter->second);
       else
         return 0;   
    }

    return &vec[0]; 
}

thanks a lot

+3
source share
12 answers

Divide your function into two parts. Make your functions in one step:
1. fill in the vector from the map.
2. create an array from a vector.
Remember to pass the map to the const link.

Main note: the GetArrayFromVector caller is responsible for freeing memory.

void FillVector( const std::map<std::string, double>& m, 
                  std::vector< double >& v, 
                  char ** names, 
                  int count )
 {
       .......
 }

 double* createArray( const std::vector< double >& v )
 {
     double* result = new double [v.size()];

     memcpy( result, &v.front(), v.size() * sizeof( double ) );

     return result; 
 }  

 // and finally your function

 double* GetArrayFromVector( const std::map<std::string, double>& m,  
                             char ** names, 
                             int count )
 {
      std::vector< double > v;
      FillVector( m, v, names, count );

      return CreateArray( v );
 }  
+7
source

- , , vec . std::vector . , , -. . .

: (1) , , (2) .

1:

std::vector<double> GetArrayFromVector(...)
{
    ...
    return vec;  // make copy of entire vec, probably not a good idea
}

2:

void GetArrayFromVector(..., std::vector<double> & vec)
{
    // compute result, store it in vec
}
+7

, .

:

double * GetArrayFromVector( std::map<std::string, double> m, vector<double> &vec, char ** names, int count )
{ 
     vec.clear();
     vec.reserve(m.size());

     for (int i=0; i<count; ++i)
     { 
         if(!names[i]) return 0;

         std::map<std::string, double>::iterator iter=m.find(name[i]);
         if(iter!=m.end())
            vec.push_back(iter->second);
         else
           return 0;   
     }

    return &vec[0]; 
}

boost::shared_array ( boost::scoped_array)

boost::shared_array<double> GetArrayFromVector( std::map<std::string, double> m, char ** names, int count )
{ 
     boost::shared_array<double> vec(new double[m.size()]);

     for (int i=0; i<count; ++i)
     { 
         if(!names[i]) return boost::shared_array<double>();

         std::map<std::string, double>::iterator iter=m.find(name[i]);
         if(iter!=m.end())
            vec[i] = iter->second;
         else
           return boost::shared_array<double>();   
     }

    return vec; 
}
+4

vec - . GetArrayFromVector(). . :

std::vector<double> GetArrayFromVector( std::map<std::string, double> m,
                         char ** names, int count )

, :

void GetArrayFromVector( std::map<std::string, double> m,
                         char ** names, int count, 
                         std::vector<double>& vec)

, :

void GetArrayFromVector( std::map<std::string, double> m,
                         char ** names, int count, 
                         std::vector<double>::iterator vecIter)

.

, , :

// you'd need to change the value to use when an element is not
// found in the map to something that suits your needs
double pred(std::map<char*, double> haystick, char* const needle) {
    std::map<char*, double>::iterator i = haystick.find(needle);
    return i != haystick.end() ? i->second : 0; 
}

int main(int argc, char* argv[])
{

   std::map<char *, double> m;
   std::vector<char *> names;
   std::vector<double> dv;

   m[ "Sasha" ] = 729.0;
   m[ "josh" ] = 8154.0;

   names.push_back("Sasha");
   names.push_back("JonSkeet");
   names.push_back("josh");

   // transform is part of STL <algorithm> header
   // it takes a container (actually a range -- [begin(), end()) 
   //                  note it is a half-open range -----------^
   // as is customary for all STL algorithms, applies the function
   // or functor specified as the last parameter to each element of
   // the sequence and writes the result back to another container
   // specified via the output iterator -- the third argument
   //
   // since I have not reserved enough elements for the vector dv
   // i cannot blindly use it -- i need a back_inserter to coax
   // transform to push_back() instead of do an insert operation
   // of course, for vectors, this is costly since reallocations 
   // may happen, but let leave the performance aside for a while!
   //
   // ok, so what about the last parameter, you ask? it has to be an
   // unary_operation. well, mostly so. but what is it that we want?
   // we want to take an iterator from the original char* (string) 
   // array and see if there an entry in the map. if there is one
   // we retrieve the associated double value and put it in dv; else,
   // we set a default value of 0 -- change it to whatever pleases you
   // maybe a std::numeric_limit<double> if it works for you.
   // 
   // you can create a functor inheriting std::unary_function and pass
   // it on. that the easy way out. but what if you already have a
   // comparator, a C-style find() function? will it work? yes, it will.
   // but we have to wrap it using the function adaptor std::ptr_fun
   // to make the compiler happy (after all it wants a unary_function, right?)
   // 
   // this simple scheme of things works very well, save for a last little
   // glitch. the comparator actually takes two parameters -- a what to search
   // and a where to search. and guess what -- the where to search is always 
   // fixed. so that gives us a good oppertunity to fix the first parameter to
   // our map<char*, double> which is exactly what std::bind1st() does. 
   // surprisingly, now that you've fixed one function, you no longer have a
   // binary function (one taking two arguments) but an unary one -- which is
   // just what you'd pass to transform. voila!
   std::transform(names.begin(), names.end(), std::back_inserter(dv), 
       std::bind1st(std::ptr_fun(pred), m));

   std::copy(dv.begin(), dv.end(), 
       std::ostream_iterator<double>(std::cout, "\n"));

    return 0;
}

:

Boost. bind()!

+2

/ , , .

0

, ( ) .

? , .

double * GetArrayFromVector( std::map<std::string, double> m, char * names[], int count )
{ 
    if(!names) return 0;

    double* vec = new double[m.size()];
    int j = 0;
    for (int i=0; i<count; ++i)
    { 
       if(!names[i]) return 0;
       std::map<std::string, double>::iterator iter=m.find(name[i]);
       if(iter!=m.end())
          vec[j++] =iter->second;
       else
         return 0;   
    }

    return vec;
} 
0

, ( "vec" ). .

( "" ) , "" , .

shared_ptr .

0

count , stl-. :

double* GetArrayFromVector(std::map<char*, double> m, char** names, int count)
{
    double* result = new double[count];
    for (int i = 0; i < count; ++i)
    { 
        if(!names[i])
        {
            delete[] result;
            return 0;
        }
        map<std::string, double>::iterator iter = m.find(name[i]);
        if(iter != m.end())
        {
            result[i] = iter->second;
        }
        else
        {
            delete[] result;
            return 0;
        }
    }
    return result;
}

, . , RAII; , , / .. ( ).

0

move constructors, , ( ) . , STLport move_source

++ 0x.

std::vector<double> double*.

0

std:: auto_ptr ( - ).

std:: auto_ptr:


    std::auto_ptr< std::vector<int> > getArray(int& count){  
       std::auto_ptr< std::vector<int> > vec(new std::vector<int>());  
          vec->push_back(10);  
          vec->push_back(12);  
          vec->push_back(14);  
          vec->push_back(16);  

          count = vec->size();  
          return vec;  
       }  

    int main(){  
       int size = 0;  
       std::auto_ptr< std::vector<int> > autoPtrVec = getArray(size);  
       int* ptr = &(*autoPtrVec)[0];  

       std::cout << "Size: " << size << std::endl;  
       for(int i=0; i<size; i++){  
          std::cout << "[" << i << "]=" << ptr[i] <<     std::endl;  
        }  

       return 0;  
    }  
0

vector:: swap. , :

void GetArrayFromVector( std::vector<double>& output, ... )
{ 
    std::vector<double> vec(m.size());

    // construct vec here...

    output.swap(vec); 
}

BTW: "GetArrayFromVector" and you pass the map?

0
source

C ++ vectors have a method data() that returns a pointer to the underlying array.

// vector::data
#include <iostream>
#include <vector>

int main ()
{
  std::vector<int> myvector (5);

  int* p = myvector.data();

  *p = 10;
  ++p;
  *p = 20;
  p[2] = 100;

  std::cout << "myvector contains:";
  for (unsigned i=0; i<myvector.size(); ++i)
    std::cout << ' ' << myvector[i];
  std::cout << '\n';

  return 0;
}

which outputs

myvector contains: 10 20 0 100 0
0
source

Source: https://habr.com/ru/post/1704164/


All Articles