вопрос по функции заполнения stl в C ++ - PullRequest
1 голос
/ 07 февраля 2010

Допустим, у меня есть такой массив:

string x[2][55];

Если я хочу заполнить его "-1", это правильный путь:

fill(&x[0][0],&x[2][55],"-1");

Это сбойкогда я пытался запустить его.Если я изменю x [2] [55] на x [1] [54], это будет работать, но не инициализирует последний элемент массива.

Вот пример, подтверждающий мою точку зрения:

  string x[2][55]; 
  x[1][54] = "x";
  fill(&x[0][0],&x[1][54],"-1");
  cout<<x[1][54]<<endl; // this print's "x"

Ответы [ 2 ]

3 голосов
/ 07 февраля 2010

Потому что, когда у вас есть многомерный массив, адрес за первым элементом немного запутан для вычисления. Ответ прост: вы делаете это:

&x[1][55]

Давайте рассмотрим, что за двумерный массив x[N][M] расположен в памяти

[0][0] [0][1] ... [0][M-1] [1][0] [1][1] ... [1][M-1] [N-1][0] .. [N-1][M-1]

Итак, самый последний элемент - [N-1][M-1], а первый элемент - [N-1][M]. Если вы берете адрес [N][M], то вы идете очень далеко от конца и перезаписываете много памяти.

Другой способ вычислить первый адрес после конца - использовать sizeof.

&x[0][0] + sizeof(x) / sizeof(std::string);
0 голосов
/ 07 февраля 2010

С формальной и педантичной точки зрения это незаконно. Повторная интерпретация 2D-массива как 1D-массива приводит к неопределенному поведению, поскольку вы буквально пытаетесь получить доступ к массиву 1D x[0] за его пределами.

На практике это будет работать (хотя некоторые инструменты анализа кода могут отловить отчет об этом как нарушение). Но чтобы правильно указать указатель на «элемент за последним», нужно быть осторожным. Он может быть указан как &x[1][55] или &x[2][0] (оба имеют одинаковый адрес).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...