2015-08-12 3 views
0

Предположим, у меня есть следующий код:Изменение векторной ссылки. Что становится недействительным?

void appendRandomNumbers(vector<double> &result) { 
    for (int i = 0; i < 10000; i++) { 
     result.push_back(rand()); 
    } 
} 

vector<double> randomlist; 
appendRandomNumbers(randomlist); 
for (double i : randomlist) cout << i << endl; 

Неоднократное push_back() операций, в конечном счете привести к перераспределению, и я подозреваю, что повреждение памяти. Действительно, vector.push_back() documentation говорит, что

Если перераспределение происходит, все итераторы, указатели и ссылки, связанные с контейнером аннулируются.

После того, как произойдет перераспределение, какой из областей будет иметь правильный вектор? Будет ли ссылка, используемая appendRandomNumbers, недействительной, поэтому она подталкивает числа к местам, которых она не должна, или будет известна «правильная» локация только с помощью appendRandomNumbers, и вектор удаляется, как только он выходит из области видимости?

Будет ли цикл печати переходить по фактическому вектору или по заштрихованной области памяти, где раньше находился вектор?

Редактировать: Большинство ответов прямо сейчас говорят, что векторная ссылка сама по себе должна быть прекрасной. У меня есть код, похожий на тот, который был выше, что вызвало повреждение памяти, когда я изменил вектор, полученный по ссылке, и прекратил иметь повреждение памяти, когда я изменил подход. Тем не менее, я не могу исключить, что я случайно установил истинную причину во время изменения. Будем экспериментировать с этим.

+2

итераторы/указатели и ссылки, указывающие на данные * в * контейнер недействительны. Сам контейнер не перемещается. Если ссылка на контейнер сама по себе недействительна, это было бы почти бесполезно. – Borgleader

+0

Что касается вашего ** Редактировать **: этот фрагмент кода неверен, или вы неверно истолковали результат. Ответы правильные. – MicroVirus

ответ

1

Я думаю, вы смущены тем, что происходит. push_back() может аннулировать итераторы и ссылки, указывающие на объекты в векторе, а не на сам вектор. В вашей ситуации не будет никакой недействительности, и ваш код будет правильным.

0

Ссылка vector<double> &result будет хорошо, проблема будет, если вы что-то, ссылающееся на , лежащую в основе памяти таких как

double& some_value = result[74]; 
result.push_back(); // assume this caused a reallocation 

Теперь some_value ссылается плохая память, то же самое будет происходить с доступом к основному массиву используя data

double* values = result.data(); 
result.push_back(); // again assume caused reallocation 

values Теперь указывает на мусор.

0

Я думаю, вы смущены тем, что становится недействительным. Все, что в вашем примере, прекрасно ведет себя. Проблема заключается в том, что вы сохраняете ссылки на данные, которыми владеет сам вектор. Например:

vector<double> v; 
v.push_back(x); 
double& first = v[0]; 
v.push_back(y); 
v.push_back(z); 
v.push_back(w); 
cout << first; 

Здесь first является ссылкой на внутренние данные v «s - который может получить аннулирована одним из push_back() с и если вы специально составили дополнительный размер, вы должны считать, что это был недействительным, поэтому cout является неопределенным поведением, потому что first - это болтливая ссылка. Это то, о чем вам следует беспокоиться - не ситуации, когда вы передаете весь vector по ссылке.

Смежные вопросы