Вектор указателей на элементы другого вектора вместо клонирования вектора - PullRequest
1 голос
/ 02 марта 2012

Я хотел бы иметь вектор z и иметь доступ к нему как z[i] или *pz[i], где *pz[i] указывает на z[i]. поэтому существует один набор значений, но есть два способа получить к нему доступ.

Это код, который у меня был:

std::vector<double> z;
std::vector<double*> pz;

for (int i = 0; i < 5; i++) {
  z.push_back(7+0.01*i);
  std::cout << i << "  z = " << z << std::endl;
  pz.push_back(&z.back());
  std::cout << i << "  pz = " << pz << std::endl;
  std::cout << i << "  *pz = " ;
  for (int j = 0; j < pz.size(); j++) {
    std::cout << "  " << *pz[j];
  }
  std::cout << std::endl;
}

z[1]=17.3;
std::cout << "z[1] = " << z[1] << std::endl;
std::cout << "*pz[1] = " << *pz[1] << std::endl;

*pz[2]=34.1;
std::cout << "z[2] = " << z[2] << std::endl;
std::cout << "*pz[2] = " << *pz[2] << std::endl;

вывод:

0  z = vector(1) [ 7 ]
0  pz = vector(1) [ 0x1d00b80 ]
0  *pz =   7
1  z = vector(2) [ 7, 7.01 ]
1  pz = vector(2) [ 0x1d00b80, 0x1d00bc8 ]
1  *pz =   1.50254e-316  7.01
2  z = vector(3) [ 7, 7.01, 7.02 ]
2  pz = vector(3) [ 0x1d00b80, 0x1d00bc8, 0x1d00bf0 ]
2  *pz =   1.50254e-316  7.01  7.02
3  z = vector(4) [ 7, 7.01, 7.02, 7.03 ]
3  pz = vector(4) [ 0x1d00b80, 0x1d00bc8, 0x1d00bf0, 0x1d00bf8 ]
3  *pz =   1.50254e-316  7.01  7.02  7.03
4  z = vector(5) [ 7, 7.01, 7.02, 7.03, 7.04 ]
4  pz = vector(5) [ 0x1d00b80, 0x1d00bc8, 0x1d00bf0, 0x1d00bf8, 0x1d00c60 ]
4  *pz =   1.50254e-316  7.01  7.02  7.03  7.04
z[1] = 17.3
*pz[1] = 7.01
z[2] = 7.02
*pz[2] = 34.1

Есть 3 проблемы:

  1. Первый элемент *pz становится неопределенным после второго нажатия.
  2. Когда я назначаю z[1], *pz[1] больше не z[1].
  3. Когда я назначаю *pz[2], он больше не присваивается z[2].

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

Ответы [ 2 ]

7 голосов
/ 02 марта 2012

Две вещи:

  1. Когда вы делаете push_back() или любую операцию, которая может привести к перераспределению вектора, вы лишаете законной силы все указатели на элементы этого вектора .
  2. В 64-битном формате указатель, вероятно, будет того же размера, что и double, поэтому вы не сэкономите память таким образом.

Если вы действительно хотите создать второй вектор с указателями на элементы первого вектора, вам необходимо сначала завершить построение первого вектора. В противном случае операции push_back() сделают недействительными указатели.

2 голосов
/ 02 марта 2012

Взгляните, чтобы увеличить мульти индекс

http://www.boost.org/doc/libs/1_46_1/libs/multi_index/doc/index.html

это может решить вашу проблему.

...