Я пишу функцию, действующую как функция thesplice
в js: при наличии массива (любого типа), удалить некоторый элемент, начинающийся с заданного индекса, и вставить новый элемент в пробел (расширить или уменьшить исходный массив, если это необходимо).
Я использую MinGw/Eclipse CDT под Windows7. Вот мой код:
void* splice(int typesize,void* arr,
int size,int start, int length,
void* stuff,int size2){
//length is the number of elements to remove
//and size2 is the number of elements to fill in the gap
//so size-gap will be the size of the new array after the function
//when gap is a minus number, the array grows
//and when gap is a positive number, the array shrinks
int gap = length-size2;
void* ptr = malloc(typesize*(size-gap));//--------(1)--------
if(ptr==NULL){
puts("error");
return NULL;
}
//now the ptr array is empty, copy the original array(arr)
//to the ptr until the 'start' index
memmove(ptr,arr,typesize*start);
//fill the new array 'stuff' into ptr starting from
//the index after 'start'
memmove(ptr+typesize*start,stuff,typesize*size2);
//and copy the rest of the original array (starting from
//the index start+length, which means starting from 'start' index
//and skip 'length' elements) into ptr
memmove(ptr+typesize*(start+size2),arr+typesize*(start+length),
typesize*(size-start-length));
return ptr;
}
и я также пишу тестовый код, фрагмент ниже для типа long long
:
int main(){
setbuf(stdout,NULL);
int start = 1;
int delete = 6;
long long* oldArray= malloc(sizeof(long long)*7);
long long* stuff = malloc(sizeof(long long)*3);
oldArray[0]=7LL;
oldArray[1]=8LL;
oldArray[2]=4LL;
oldArray[3]=1LL;
oldArray[4]=55LL;
oldArray[5]=67LL;
oldArray[6]=71LL;
stuff[0]=111LL;
stuff[1]=233LL;
stuff[2]=377LL;
int newsize = 7-(delete-3);
void* newArray = splice(sizeof(long long),oldArray,7,start,delete,stuff,3);
if(newArray){
//------------crash happens here-----------
//free(oldArray);
//-------------
oldArray = newArray;
int i=0;
for(;i<newsize;i++){
printf("%I64d\n",oldArray[i]);
}
}
return 0;
}
Он должен вывести 7, 111 233 и 377 (удалить шесть элементов из индекса 1 и вставить в массив 111 233 и 377).
Я тестировал массивы типов char, int и long, и во всех ситуациях код работал. Кроме одной проблемы: не могу освободить старый массив. Похоже, что блок памяти не может быть восстановлен после того, как к нему несколько раз обращался memmove
.
Если я изменю malloc на realloc в (1), и free() не сработает, но я больше не смогу заставить функцию работать правильно (и я не уверен, действительно ли работала функция free() или нет).
Пожалуйста, дайте несколько советов о том, как возникает эта проблема и как я могу улучшить свой код.
memove()
по одному, чтобы увидеть, какой из них (если есть) вызывает это. - person uesp   schedule 28.11.2014