0

How do I avoid copying whole values of vector kws into req_kws (the vector of vectors) below, while keeping two containers kws and req_kws in my code?

 vector<vector<string>> req_kws;
 for (string& request : requests) { 
    vector<string>& kws = req_kws.back(); //<-- define &kws to empty req_kws
    kws = split(kwsStr, ",");   //split is a parsing function upon string kwsStr
    req_kws.push_back(kws);
 }

I used in line number 3

vector<string>& kws = req_kws.back();

In this way, instead of storing all values of kws vector, only its reference is stored into req_kws.

But, I am getting a segmentation fault during the runtime. Is there a way to fix it?

Thank you for your help.

Additional note;

Please note my constraint stated above that I need to keep both line number 4 (kws) and 5 (req_kws) intact, and want to use line number 3 of reference (&) or something similar to save the execution time from the same values being stored to both kws and req_kws. I have the other parts of the codes with the same problem, which are more complicate so that I can Not simply combine two lines of 4 and 5 into one.

Additional Question (Similar problem):

Thank you for your solution down below. However, how about the following case, which is similar as above but more complicated.

vector<unordered_map<string, string>> ads_kwsBids;
for (const auto& kwBid : kwsBids) {
    …
    unordered_map<string, string>& kwsBidsMap = ads_kwsBids.back(); //to prevent from being whole container copied
    for (unsigned j = 0; j < nsize; j++) {
        unsigned jdx = 2 * j;
        kwsBidsMap[splitedStr[jdx]] = splitedStr[jdx + 1];// constructing map kwsBidsMap
    }
    ads_kwsBids.push_back(kwsBidsMap);
}

In line number 4, that is,

unordered_map<string, string>& kwsBidsMap = ads_kwsBids.back();

Because of the reference &, it yields the segmentation fault. But, the reference is also the one that prevents kwsBidMap from being copied into ads_kwsBids. Is there a way still to use the reference & on kwsBidMap and not get the segmentation fault?

syang
  • 1
  • 2
  • As far as i can see in your code, req_kws is empty, calling "back" method on empty vector will produce undefined behavior. – Ayush Mishra May 29 '20 at 01:44
  • You are right that the segmentation fault is caused by calling req_kws being empty. However, is there a way to avoid the runtime failure? Please note my contraint that I need to keep both line number 4 (kws) and 5 (req_kws) intact, and want to use line number 3 of reference (&) or something similar to save the execution time from the same values being stored to both kws and req_kws. – syang May 29 '20 at 03:45

2 Answers2

0

In the code shown, req_kws is an empty vector. Calling back() on an empty vector is Undefined Behavior. You either need to add an element to the vector first, or rewrite the code to not depend on having a value present.

From what I can gather you are trying to do, I think a simple

req_kws.push_back(split(request, ","));

should suffice.

Alternatively, you can rewrite the loop as

for (string& request : requests) { 
    req_kws.push_back(split(request, ","));
    vector<string>& kws = req_kws.back();
}

This will split the request string, store it in the req_kws vector, then create the kws reference to that newly added element. Depending on what else you do with it, you may need to add req_kws.reserve(requests.size()); before the for loop to avoid reallocations when adding to the vector.

1201ProgramAlarm
  • 32,384
  • 7
  • 42
  • 56
  • Thank you for your answer. I raised a similar yet slightly more complicated question by editing the above. Would you take a look at it? – syang May 29 '20 at 19:08
0

This is my version of the solution to the problem.

vector<unordered_map<string, string>> ads_kwsBids;
for (const auto& kwBid : kwsBids) {
    …
    //Initialize the container with default value.
    ads_kwsBids.push_back(unordered_map<string, string>());
    //& used to prevent from being whole container copyed
    unordered_map<string, string>& kwsBidsMap = ads_kwsBids.back();
    for (unsigned j = 0; j < nsize; j++) {
        unsigned jdx = 2 * j;
        //Put kwsBids into a hash map
        kwsBidsMap[splitedStr[jdx]] = splitedStr[jdx + 1];// constructing map kwsBidsMap
    }
}
syang
  • 1
  • 2