Danny96 Ответов: 1

Вектор итераторов из разных контейнеров ошибки


Здравствуйте, я пытаюсь объединить векторы, когда получаю данные от кабеля в моем цикле while. Я ищу ...
copy
метод в массиве C++ много, и я видел примеры, такие как мой код, который должен работать правильно, однако я получаю ошибку, как в названии. Я поставил точки останова и наблюдал;
copy(GetIntArrayFromCharArray(vec).begin(), GetIntArrayFromCharArray(vec).end(), it+intData.size());
в этой строке он звонит в первый раз
GetIntArrayFromCharArray
все было в порядке, значит, он зовет ее к себе.
.end()
затем появляется ошибка. Я тоже смотрел итератор, он не пустой. Я не мог понять, что мне делать.

(PrevFrameFragmentNo и другие переменные предназначены только для отслеживания кадра и сегментов в пакетных данных UDP.)

Что я уже пробовал:

ЭТОТ ФРАГМЕНТ КОДА НАХОДИТСЯ В ЦИКЛЕ WHILE, ПРИНИМАЕТ ДАННЫЕ В БУФЕР
//char buf ----> vecor<char> vec
		int n = sizeof(buf) / sizeof(*buf);//number of elements
		vector<char> vec(buf, buf + n);

		 


		if (FrameFragmentNo == 1)// First fragment
		{
			intData = GetIntArrayFromCharArray(vec);
			PrevFrameFragmentNo = FrameFragmentNo;
		}
		else if (FrameFragmentNo <= TotalFragmentCount)  // Other Fragments
		{
			vector<uint16_t> concatAry;
			std::vector<uint16_t>::iterator it;

			
			
			
			concatAry.assign(intData.begin(), intData.end());
			

			it = concatAry.begin();
			//PROBLEMATIC LINE IS HERE
			copy(GetIntArrayFromCharArray(vec).begin(), GetIntArrayFromCharArray(vec).end(), it+intData.size());

			
			intData = concatAry;
			PrevFrameFragmentNo = FrameFragmentNo;
			count++;
		}


Этот код является методом GetIntArrayFromCharArray()
vector<uint16_t> GetIntArrayFromCharArray(vector<char> arr)
{
	
	if ((arr.size() % 2) == 1)
		arr.resize(arr.size()+1);
	


	vector<uint16_t> intArray;

	for (int i = 0; i < arr.size(); i += 2)
		intArray.push_back((uint16_t)((arr[i] << 8) | arr[i + 1]));

	return intArray;
}

1 Ответов

Рейтинг:
8

Stefan_Lang

Функция GetIntArrayFromCharArray создает копию, поэтому ваши вызовы begin() и end() относятся к двум разным массивам! Это отражено буквально в сообщении об ошибке - все, что вам нужно сделать, это прочитать и понять его. ;-)

[..] (отрежьте пересмотренные части решения - см. ниже)

П.[...]С.:
[...]
Извините, мне нужно пересмотреть свое решение в третий раз:
Похоже, вы пытаетесь добавить несколько преобразованных массивов int в цикл: в первый раз вы просто вызываете

GetIntArrayFromCharArray
- и это прекрасно. В следующих итерациях цикла вы преобразуете массив char и пытаетесь добавить его к существующему массиву int.

Что касается решения, которое вы ищете, то первое, что вам нужно, - это локальная переменная для хранения преобразованного массива int, как указано выше, а затем вам нужно добавить (), например:
auto myIntArray = GetIntArrayFromCharArray(vec);
concatAry.append(myIntArray.begin(), myIntArray.end());

Функция copy() может использоваться только для копирования данных в уже выделенное место. Однако ваш конкатарий достаточно велик, чтобы вместить только существующие элементы, поэтому вместо него вам нужно использовать функцию append (). С другой стороны, вы могли бы сначала использовать resize (), но зачем использовать два вызова функций, когда вы можете сделать это в одном? ;-)


Danny96

вы правы, я исправляю его, но теперь он дает ошибку "не может искать итератор после конца", итератор не пуст, я не понимаю, почему компилятор борется с итератором, у вас есть идея? :(

phil.o

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

Danny96

Я уже нахожусь в режиме отладки, и источник больше, чем целевой массив, который я уже знаю, но это векторы, это не должно быть проблемой, я думал

phil.o

Это не проблема, когда вы используете право push_back метод добавления элементов в конце вектора.
Однако это проблема, когда вы имеете дело непосредственно с итераторами. Итераторы-это указатели; они указывают на адрес памяти в пространстве приложения. Если вы манипулируете указателем арифметически, вы можете в конечном итоге сослаться на адрес памяти, который находится за пределами области, назначенной вектору. Это типичное переполнение буфера.

Stefan_Lang

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

Stefan_Lang

Вы правы, что std::vector может автоматически изменять размер в соответствии с его потребностями, но вам нужно использовать соответствующие методы. функция copy() не изменяет размер, она пытается перезаписать память в уже зарезервированном месте. Дру, push_back(), вставить () и append() все настройки выделенной памяти, чтобы соответствовать добавленные данные.

Stefan_Lang

Ладно, я не проверял детали вашего кода. Я не заметил, что вы уже создали копию и сохранили ее в intData. В этом случае, конечно, первая строка кода, который я опубликовал, не нужна, а вторая строка должна быть изменена, чтобы использовать intData вместо myIntArray.

Если вы внимательно прочтете мое объяснение, вам может прийти в голову, что intData-это другая копия, чем myIntArray из сегмента кода, который я опубликовал выше. Поэтому неразумно оперировать этими двумя разными объектами - что бы вы ни делали с одним объектом, это не отражается на состоянии другого объекта!

Danny96

Я понимаю, Спасибо