Как избежать копирования целых значений вектора в другой контейнер - PullRequest
0 голосов
/ 28 мая 2020

Как мне избежать копирования целых значений вектора kws в req_kws (вектор векторов) ниже, сохранив при этом два контейнера kws и req_kws в моем коде?

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

Я использовал в строке номер 3

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

Таким образом, вместо сохранения всех значений kws вектора, только его ссылка сохраняется в req_kws.

Но, я я получаю ошибку сегментации во время выполнения. Есть способ исправить?

Спасибо за вашу помощь.

Дополнительное примечание;

Обратите внимание на мое ограничение, указанное выше, что мне нужно сохранить обе строки номер 4 (kws) и 5 ​​(req_kws) неповрежденными, и хотите использовать строку номер 3 ссылки (&) или что-то подобное, чтобы сэкономить время выполнения из-за того, что одни и те же значения сохраняются как в kws, так и в req_kws. У меня есть другие части кода с той же проблемой, которые более сложны, поэтому я не могу просто объединить две строки из 4 и 5 в одну.

Дополнительный вопрос (аналогичная проблема):

Спасибо за ваше решение ниже. Однако как насчет следующего случая, который похож на предыдущий, но более сложный.

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

В строке номер 4, то есть

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

Из-за ссылки & , это приводит к ошибке сегментации. Но ссылка также предотвращает копирование kwsBidMap в ads_kwsBids. Есть ли способ использовать ссылку & на kwsBidMap и не получить ошибку сегментации?

Ответы [ 2 ]

0 голосов
/ 24 июня 2020

Это мой вариант решения проблемы.

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
    }
}
0 голосов
/ 29 мая 2020

В показанном коде req_kws - пустой вектор. Вызов back() для пустого вектора - это неопределенное поведение. Вам нужно либо сначала добавить элемент к вектору, либо переписать код, чтобы он не зависел от наличия значения.

Насколько я понимаю, вы пытаетесь сделать, я думаю, что простой

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

должно хватить.

В качестве альтернативы вы можете переписать l oop как

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

Это разделит строку запроса, сохранит ее в векторе req_kws, затем создайте ссылку kws на этот недавно добавленный элемент. В зависимости от того, что еще вы с ним делаете, вам может потребоваться добавить req_kws.reserve(requests.size()); перед for l oop, чтобы избежать перераспределения при добавлении к вектору.

...