11. februar 2003 - 17:15Der er
24 kommentarer og 5 løsninger
Resize af array ?
Jeg vil bruge FindFirstFile() til at søge efter filer og mapper rekursivt, og har i min VB udgave lavet et Static array der bliver ReDim'et (resized) hvis der er for få elementer (sizeof()+100 bliver den nye størrelse), men jeg kan ikke rigtigt kringle hvordan dette kan lade sig gøre i VC++ .. eller, om det KAN lade sig gøre .. ?
Hvis det kan, er der nogle der har en idé til hvordan ?
Det fremgår ikke rigtigt hvad fordelen med en vector er.. En vector udvides automatisk når der ikke er plads til et element - sikkert det samme som sker i dit basic program. Altså en pæn (og vel testet) indpakning af Arnes forslag.
Hvis du tager udgangspunkt i sorenos kode skal du huske at kopiere navnene på de filer du får tilbage fra FindFirstFile, hvis du laver en vektor med char pointers bliver der ikke kopieret. F.eks. :
>>arne_v "Et program der bruger den funktion vil med stor sandsynelighed crashe hurtigt p.g.a. memory corruption"
Hvad faen er det for noed at fyre af uden at forklare sig?! Jeg smed noget kode efter jer hoeder for at illustrere en idé og så bliver jeg kritisseret uden at man gidder spilde tid på at forklare sig i ord?...
Det er lidt svært at forklare på dansk, men hvis du kører det program (som jeg altså brugte 10 minutter på at skrive), så burde min pointe fremgå klart.
Jeg kan godt prøve: en char pointer som argument er pass by reference for det bagvedliggende char array men pass by value for pointeren selv og derfor bør man ikke ændre den men istedetfor sende adressen på pointeren over.
og man ser at redim1 (som bruger char *p) går grueligt galt da man efter return fra redim1 står med en pointer som peger på et stykke memory, som man har delete'd inde i redim1.
redim2 gør derimod det som man ønsker og man står med en pointer til det nye stykke memory.
Der sker ikke det fjerneste ved at man ændrer den.
*Men* man skal være klar over at ændringerne forsvinder når man udfører return.
Og i dette tilfælde hvor man har free'et den gamle pointer er det katastrofalt.
Generelt vil jeg kalde det meget dårlig skik at ændre i pass by value argumenter.
Lav en temporær variabel og assign til den og ændre i den temporære. Så er der ikke nogen som er i tvivl om at ændringerne ikke føres tilbage ved return.
Du kunne også bruge pointer to pointer ligesom i min redim2 altså:
void ResizeArr(char **arr, int oldLen, int newLen){ if(newLen < 0 || oldLen < 0)throw string("Dumeflad! En længde kan ikke være mindre end 0!"); char *tmp, *newArr=new char[newLen]; int uLen=0; if(oldLen < newLen)uLen=oldLen; else uLen=newLen; for(int i=0;i < uLen;i++) newArr[i]=(*arr)[i]; tmp=(*arr); (*arr)=newArr; delete[] tmp; }
al1407 har ikke opgivet hvilken type hans array er, så for liiige at få det hele med:
//Ret 'char' til den type dit array skal være #define ARRTYPE char void ResizeArr(ARRTYPE **arr, unsigned int oldLen, unsigned int newLen){ ARRTYPE *newArr=new ARRTYPE[newLen]; memcpy(newArr, *arr, min(oldLen, newLen)); delete[] *arr; *arr=newArr; }
Der er mindst en ting man skal huske - størrelsen af de data der skal kopieres :
//Ret 'char' til den type dit array skal være #define ARRTYPE char void ResizeArr(ARRTYPE **arr, unsigned int oldLen, unsigned int newLen){ ARRTYPE *newArr=new ARRTYPE[newLen]; memcpy(newArr, *arr, sizeof(ARRTYPE) * min(oldLen, newLen)); delete[] *arr; *arr=newArr; }
Personligt foretrækker jeg dog en template til sådan noget her :
template <class T> void ResizeArr( T ** arr, unsigned int oldLen, unsigned int newLen) { T *newArr=new T[newLen]; memcpy(newArr, *arr, sizeof(T) * min(oldLen, newLen)); delete[] *arr; *arr=newArr; }
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.