#c #for-loop #vector #infinite-loop #implicit-conversion
Вопрос:
Если входной массив пуст, то array.size()
должно быть 0. Первое for
, что идет от 0
до array.size() - 1
, должно означать , что оно идет от 0
до -1
, верно?
for
Тогда это не следует вводить, и функция должна возвращать значение счетчика инверсий, которое было бы 0
Но этого не происходит, и код входит в бесконечный цикл. Почему это происходит?
Вот код:
#include <vector>
#include <iostream>
using namespace std;
int countInversions(vector<int> array)
{
int inversionsCounter = 0;
for (int i = 0; i < array.size() - 1; i)
for (int j = i 1; j < array.size(); j)
if (array[i] > array[j])
inversionsCounter;
return inversionsCounter;
}
int main()
{
vector<int> array = {};
cout << array.size();
cout << countInversions(array);
}
Комментарии:
1. Я верю
array.size() - 1
, что переполняется.2. Сначала решите : C4018: ‘ Это явная подсказка от компилятора. (Я никогда не использую целые числа со знаком для значений, которые всегда должны быть >0, используйте тот же тип, что и возвращаемый array.size()).
3. Пожалуйста, опубликуйте свой фактический код, который вызывает проблему. В опубликованном коде вы вообще не вызываете функцию
countInversions
.4. Технически цикл не бесконечен, но он будет длиться довольно долго.
array
имеет нулевой размер, поэтомуarray.size() - 1
будет получено наибольшее значение, котороеstd::size_t
может представлять a, которое часто (в зависимости от вашего компилятора и хост-системы) является довольно большим значением (например4294967295
, в 32-разрядной системе или18,446,744,073,709,551,615
в 64-разрядной системе).5. @maverick.01: Как правило, ваш опубликованный код должен быть в состоянии воспроизвести проблему. Читателям вашего вопроса не должно быть необходимости думать о том, какие части вашего кода должны быть раскомментированы, а какие нет, чтобы воспроизвести проблему. Не сразу стало очевидно, что первая часть прокомментированного кода должна оставаться деактивированной, но вторая часть прокомментированного кода должна быть повторно активирована путем раскомментирования. Это затруднило понимание вашего вопроса. Тем временем кто-то другой отредактировал ваш вопрос, чтобы исправить это.
Ответ №1:
Тип возвращаемого значения функции-члена size
шаблона класса std::vector
-это целочисленный тип без знака, обычно эквивалентный типу size_t
.
Таким образом, в состоянии цикла for
for (int i = 0; i < array.size() - 1; i)
из — за обычных арифметических преобразований оба операнда выражения
i < array.size() - 1
преобразуются в целочисленный тип без знака, соответствующий данному типу std::vector<int>::size_type
. В результате выражение array.size() - 1
преобразуется в максимальное значение типа, когда функция-член size
возвращает 0.
Вот демонстрационная программа.
#include <iostream>
#include <iomanip>
int main()
{
std::cout << size_t( -1 ) << 'n';
std::cout << std::boolalpha << ( 0 < size_t( -1 ) ) << 'n';
return 0;
}
Его выход составляет
18446744073709551615
true
Поэтому, когда функция-член size
возвращает 0, на самом деле у вас есть цикл, подобный этому
for (int i = 0; i < 18446744073709551615; i)
Вместо типа int
вы должны использовать, по крайней мере, тип size_t
для индексов. И внешняя петля должна выглядеть так
for ( size_t i = 0; i < array.size(); i )
Ответ №2:
Тип возвращаемого значения для метода size() в vector<> -<> size_t
, целочисленное значение без знака — часто просто unsigned int
. Этот тип , size_t
, не имеет знака и не может содержать отрицательных чисел. В большинстве случаев компилятор предупредит вас об этом.
Однако, когда пришло время выполнить код, компилятор заменяет форму «дополнения» целого числа со знаком -1 (вычисляется по размеру() — 1 ) на size_t
тип (без знака).
Это число со знаком -1 часто бывает очень большим, когда предпринимается попытка представить его как число без подписи. Большая часть специфики здесь зависит от вашей конкретной машины и деталей компилятора.
Это означает, что ваш внешний цикл for for (int i = 0; i < array.size() - 1; i)
выполняется не в бесконечном цикле, а в очень длинном.
Ответ №3:
приведите array.size() к int, в противном случае похожему …
(int)array.size()