0

Below is code through error as std::bad_alloc. I am getting error on line obj_[key[i]] = value[i]; . please help me to fix it .

 #include<iostream>
 #include<map>
  using namespace std;

 namespace {
         const std::string key1 = "s1";
         const std::string key2 = "s2";

         const std::string value1 = "v1";
         const std::string value2= "v2";
 }

 int main()
 {

         std::string key[3] = {
                 key1, key2};
          std::string value[3] = {
                  value1,value2 };
         std::map<std::string,std::string> obj_;

         for (size_t i = 0; i < sizeof(key); ++i) { // here its thow std::bad_alloc
                 obj_[key[i]] = value[i];
            }
}
josp
  • 97
  • 5

4 Answers4

0

sizeof(key) is the size of the array in bytes. It's not the amount of elements.

Instead you should be using std::extent_v<decltype(key)>. (Requires #include <type_traits>.)

Pre-C++17 alternative: std::extent<decltype(key)>::value. (Requires #include <type_traits> as well.)

If that's too fancy for your taste, there's a poor man's alternative: sizeof(key)/sizeof(key[0]).

Or just hardcode the 3.

HolyBlackCat
  • 78,603
  • 9
  • 131
  • 207
  • can you please give example code which give size using ur below suggestion. Instead you should be using std::extent_v. (Requires #include .) – josp Aug 21 '18 at 05:12
  • @josp You just replace `sizeof(key)` with `std::extent_v`. And also add `#include ` on top of the file. – HolyBlackCat Aug 21 '18 at 05:14
  • Below error is throw : mapex.cc: In function ‘int main()’: mapex.cc:23:25: error: ‘extent_v’ is not a member of ‘std’ for (size_t i = 0; i < std::extent_v ; ++i) { ^ mapex.cc:23:39: error: expected primary-expression before ‘decltype’ for (size_t i = 0; i < std::extent_v ; ++i) { – josp Aug 21 '18 at 06:08
  • compile with c++ -std=c++11 mapex.cc – josp Aug 21 '18 at 06:09
  • @josp It requires C++17. Try with `-std=c++17`. If the flag doesn't work, it means that your compiler is too old. Update it, or try the other two options. – HolyBlackCat Aug 21 '18 at 16:24
0

sizeof(key) = 96 (on os 64bit). To get the size of the array you have to divide this number by sizeof(std::string) (which is 32 (on os 64bit)):

for (size_t i = 0; i < sizeof(key) / sizeof(std::string); ++i) {
     obj_[key[i]] = value[i];
}
Coral Kashri
  • 3,436
  • 2
  • 10
  • 22
-1

Don't use sizeof(key) here:

for (size_t i = 0; i <  sizeof(key); ++i) { // here its thow std::bad_alloc
        obj_[key[i]] = value[i];
    }

EDIT 21.08.2018 use (sizeof(key)/sizeof(*key)) instead:

for (size_t i = 0; i <  (sizeof(key)/sizeof(*key)); ++i) { // here its thow std::bad_alloc
        obj_[key[i]] = value[i];
    }
lujobi
  • 44
  • 1
  • 5
-1

When you use sizeof() it returns the size in bytes of the object, not the number of elements as you seem to be expecting. Additionally when using the operator [] you access directly the encapsulated data inside the array, with no bound check, this combination is probably your error source. You can do the math and figure out how many elements you have.

Since you previously know your array size, you can use an std::array instead.

std::array<std::string,3> key = {key1, key2, ""}; //you only used two values in your code
for (size_t i = 0; i < key.size(); ++i) {
  //your instructions
}

It is a bit odd that even explicitly setting your array's size, you still need to inquire about its size in the loop. Supposing this is an unintended feature of your problem statement, and you don't know its size in advance, I would recommend you to use an std::vector instead.