[cdev] задача 4, 135 гр.

Grigoriy A. Sitkarev sitkarev на komitex.ru
Сб Дек 11 22:52:13 MSK 2010


Возможно, я не всё заметил.

Возможно, что-то появилось неверное и сегодня.

Например, функция следующая:

void
parray_delete(struct parray *pa, void *ptr)
{
	int i;
	for(i = 0; i < pa->nelems; ++i){
		if (pa->data[i] == ptr){
			break;
		}
	}
	
	if (i < pa->nelems){
		if (i == pa->nelems - 1) {
			--pa->nelems;
		}
		if (i < pa->nelems-1){
			--pa->nelems;
			memmove(pa->data + i,
			   pa->data + i + 1,
			   (pa->nelems - (i + 1))*sizeof(void *));
		}
	} else {
		fprintf(stderr, "elems cann't delete\n");
	}
}

И вроде бы всё хорошо, но вот есть два нюанса:

1. Там где шло условие if (i == pa->nelems - 1) и после опять идёт if (i 
< pa->nelems-1) хотя лучше бы было сделать:

if (i == pa->nelems - 1) {
	--pa->nelems;
} else {
	...
}

И яснее и читается проще. А дальше досада - вроде бы алгоритм расчёта 
количества удаляемых элементов верный, но вы сначала уменьшили 
pa->nelems на один, а потом вычитаете из него на единицу больше чем 
нужно. Пусть было 4-е элемента в массиве, удаляли мы индекс 1. Если 
вычесть из 4-х - (1+1)=2, 4-2=2, получим сколько элементов нужно 
сместить в memmove(), но (!!!) у вас уже там размер-то не 4, а 3, т.к. 
вы уменьшили значение pa->nelems ДО этого на единицу. Поэтому надо 
считать как (pa->nelems-i) или же делать инкремент после memmove().

Я всё равно буду перепроверять ваш финальный исходник, просто когда я 
бегу глазами мне достаточно указать на одну-две ошибки, этого достаточно 
чтобы отправить задание на доделку.

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

--
Г.А.

Ксения Оботурова пишет:
> memmove(pa->data + nth, pa->data + nth + pa->nelems - nth,
> (pa->nelems - (pa->nelems - nth))*sizeof(void *));
> nth сокращаются и мы смело выходим за границы массива. Причем перемещаем
> зачем-то nth элементов, а должны перемещать другое кол-во.
> 
> это я не знаю откуда вы взяли, сейчас когда я отправила задачу последний раз, такого фрагмента кода, вообще не было!!!
> 






Подробная информация о списке рассылки cdev