03. marts 2008 - 13:22Der er
15 kommentarer og 2 løsninger
set_size, dynamisk allokering af Array
Hej, jeg har lavet en klasse, hvor brugeren ved oprettelse af et objekt sætter størrelsen af et dynamisk array explicit. Senere har jeg så tilføjet en setfunktion, som ændrer på størrelsen af mit Array.
Jeg får følgende fejl, når jeg forsøger at compile nedstående:
Size er en medlemsdata, som jeg har initialiseret ved "member initializing". Hvis jeg i stedet for at skrive size skriver, "sizeof(vaerdiPtr)", så virker det... men burde det ikke virke alligevel? I min constructor, hvor jeg opretter mit array, så giver jeg den nemlig størrelsen af size, så... jeg forstår ikke hvorfor jeg får ovenstående fejl.
void CirkulearBuffer::setSize( const int nySize ) { Point LokalArray[size];
if ( nySize > 0) { if ( nySize < size ) { for ( int i = (size - nySize); i < size; i++ ) LokalArray[i] = vaerdiPtr[i]; } else { for ( int i = 0; i < size; i++ ) LokalArray[i] = vaerdiPtr[i]; } delete vaerdiPtr; vaerdiPtr = new Point[nySize];
for (int i = 0; i < nySize; i++) vaerdiPtr[i] = LokalArray[i]; } }
Du kan ikke allokere et array af ukendt stoerelse paa stacken, saa linien Point LokalArray[size]; er ikke gyldig. Du skal i stedet allokere det med new(Og saa huske at delete det ogsaa :}
Jeg har allerede en dynamisk allokeret Array. Jeg ønsker blot at tillade brugeren af klassen at ændre arrayets størrelse. Det gør jeg ved først at oprette et lokalt array, som jeg initialiserer med indholdet af mit dynamisk allokerede Array. Dernæst sletter jeg det dynamisk allokerede array og opretter et nyt dynamisk allokeret Array, med den størrelse brugeren ønsker. Til sidst initialiserer jeg den med det, som jeg har kopieret over i mit lokale array, som kun eksisterer i funktionens scope.
Variablen size er som sagt en medlemsdata og hvis jeg skriver "cout << size;" i funktionen, så udskriver den 8, som er hvad jeg har initialiseret den med explicit ved oprettelse af objektet. Mærkeligt...
Til Arne_v:
Eftersom min underviser ikke kunne se hvad der var galt, så må du jo have ret. Det skal lige siges til min undervisers forsvar, at dette var en "uofficiel" ekstra opgave og at han kun havde de sidste 2 minutter af undervisningen til at finde fejlen, samtidig med at han skulle krydse folk af sin godkendelsesliste :)
Under alle omstændigheder, så vil jeg sende din tråd til ham og høre, om han har input til det. Tusind tak for hjælpen.
Forresten, hvor finder jeg oplysninger om den compiler Visual Studio 2008 bruger og kan jeg skifte compileren uden besvær? Du må gerne vedlægge et svar :)
Jeg kan ikke se hvad der er saa maerkeligt, men lad mig proeve at omformulere mig.
Hvis du vil allokere et array paa stacken(Point LokalArray[size]) saa skal stoerelsen af det array du allokere vaere konstant og kunne bestemmes paa compile time.
Dette er ikke tilfaeldet her, da din stoerelse(din const int mySize) er en variable som kan have forskellige vaerdier.
Meningen med funktionen er jo, at man skal kunne ændre arrayets størrelse ved hjælp af ovenstående funktion. Derfor skal størrelsen være en variabel. Det jeg finder mærkeligt er, at følgende ikke virker, men jeg går ud fra at Arne har ret i, at det er compileren som er for gammel..., hvad mener du?
#include <iostream> using namespace std;
void funktion( const int x ) { int Array[x]; }
void main() { funktion(5); }
Angående din idé om at allokere et nyt array med new og direkte kopiere indholdet, så har du selvfølgelig ret, men... jeg har desværre undladt at fortælle, at pointeren "vaerdiPtr" er en private medlemspointer, som bliver brugt i andre funktioner. Derfor skal det være den eneste pointer der skal pege på det, som jeg gemmer i heapen. Men ellers tak :)
Du kan sagtens lave det saa vaerdiPtr bliver den eneste pointer der peger paa dine data, den anden midlertidige pointer forsvinder jo naar funktionen slutter.
Og void funktion( const int x ) { int Array[x]; }
Er ikke, og har aldrig vaeret gyldig c eller c++ kode, for naar du allokere et array paa den maade(Du allokere det paa stacken) saa skal arrayts stoerelse vaere kendt paa compile time(Naar du oversaetter programmet) og det er det ikke i dette tilfaelde.
void CirkulearBuffer::setSize( const int nySize ) {
if ( nySize > 0) { if ( nySize < size ) { // Denne del kan du selv lave. Ps: Overvej hvilke data fra det gamle array du vil kopiere // Er du sikker paa at du altid vil have dem der ligger foerst i arrayet? } else { // Lav et nyt og stoerrer array Point *newPointArray=new PointArray[nySize];
for ( int i = 0; i < size; i++ ) { newPointArray[i] = vaerdiPtr[i]; } delete[] vaerdiPtr; // Slet det gamle array(Bemarke delete[]) vaerdiPtr = new PointPoitnArray; // Og saet vaerdiPtr til det nye array } }
Så for at få det banket helt fast, så kan man simpelthen ikke lave en funktion, som alt afhængig af input allokere en bestemt størrelse af et array i heapen?
ugh, jeg har på fornemmelsen at jeg kun har forvirret mig selv og at opgaven vi fik var uigennemtænkt, for som du siger så kan man kun definere størrelsen på et Array compiletime. Lige så snart Arne har svaret, så accepterer jeg begge svar.
quote: Så for at få det banket helt fast, så kan man simpelthen ikke lave en funktion, som alt afhængig af input allokere en bestemt størrelse af et array i heapen?
Jeg tror du mener stacken, ikke heapen. Stacken er der hvor du allokere lokale variable fra, og her er det korrekt at du kan kan allokere ting som du kender stoerles paa ved compile time. Saa
void funktion( const int x ) { int Array[x]; } er ikke muligt;
Heapen er der hvor du allokere fra med new/malloc og der kan du godt bestemme stoerelsen ved runtime.
Tak for en detaljeret gennemgang. Jeg er som sagt forholdsvis ny til c++ programmering og har først her på det sidste lært om dynamisk allokering. Jeg havde blot den opfattelse, at man kunne initialisere et lokalt array runtime... jeg synes jeg har gjort det mange gange før og jeg var stensikker på at følgende ville compile inden jeg prøvede det. Jeg tror jeg vil dykke ned i min c++ bog og læse hele afsnittet om arrays.
Aha der kan man bare se. Men det en sjovt nok kun gyldigt i C, og ikke i c++ (Selvom lidt googling siger at g++ ogsaa acceptere(Eller i hvert fald har gjort)) variable length arrays i c++.
Hmmm jeg synes det var spild af tid at læse i min bog, men fremover vil jeg huske på, at et dynamisk allokeret array kan dimensioneres runtime (vidste jeg godt i forvejen) og et lokal erklæret array kun kan dimensioneres compiletime.
Men som det ser ud nu er featuren heller ikke med i C++0x.
Hardcore C++ folkene kan slet ikke lide C style arrays. De mener at man skal bruge STL i.s.f. f.eks. vector.
void f(int n) { vector<int> a(n); for(int i = 0; i < n; i++) { a[i] = i; } for(int i = 0; i < n; i++) { cout << a[i] << endl; } }
Synes godt om
Ny brugerNybegynder
Din løsning...
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.
Kæmpe prisstigninger hos VMware sender danske kunder i armene på AWS: "Prisreguleringer er noget, der trigger kunder til at træffe beslutninger," siger AWS