Permalänk
Medlem

dynamisk array i C++

Hej
Jag håller på med att som läser in ett viss antal heltal som ska lagras i en vektor som allokeras dynamiskt (d.v.s. en pekare till ett vektorutrymme). Användaren ska i en repetition kunna välja om ett nytt tal ska läsas in och programmet ska då allokera om nytt utrymme för vektorn, enligt följande algoritm:

1. Reservera en ny vektor som är ett element större än den gamla.
2. Kopiera samtliga värden från den gamla vektorn till den nya.
3. Frigör utrymmet som den gamla pekaren pekade på.
4. Tilldela pekaren (talvektorn) adressvärdet för den nya vektorn

Problemet är att jag kunde inte få den nye vectorn som jag ska spara talet i att fungera

#include <iostream> #include <conio.h> using namespace std; const char ESC = 27; int talIn(int in); void display(int *m, int &n); int main() { int t=0, i=1; int *p = NULL; p = new int[i]; do { int j=0; p[t] = talIn(j); ++i; ++t; cout << "Tryck valfri tangent for att fortsatta eller <ESC> for att avsluta" << endl; }while(_getch() != ESC); const int SIZE = i; int arr[SIZE]; for (int v=0; v<i; v++) { arr[v] = p[v]; } delete[] p; p = NULL; display(arr, t); return 0; } int talIn(int in) { cout << "Skriv in ett tal: "; cin >> in; cout << endl; return in; } void display(int *m, int &n) { do { for (int v =0 ; v<n || v!=n ; ++v) { cout << m[v] << endl; } }while (_getch() != ESC); }

Är det nån som har en lösning på detta?
ALL hjälp uppskattas.

Permalänk
Hedersmedlem
Skrivet av Houlan:

do { int j=0; p[t] = talIn(j); ++i; ++t; cout << "Tryck valfri tangent for att fortsatta eller <ESC> for att avsluta" << endl; }while(_getch() != ESC);

Ett problem är att du inte skapar något nytt fält; i loopens andra varv kommer man försöka skriva till p[1] trots att p endast har längden 1.

Permalänk
Medlem

Jag ändrade lite på koden

#include <iostream> #include <conio.h> using namespace std; const char ESC = 27; int talIn(int in); void display(int *m, int &n); int main() { int t=0, i=1; int *p = NULL; p = new int[i]; do { int j=0; p[t] = talIn(j); ++i; ++t; cout << "Tryck valfri tangent for att fortsatta eller <ESC> for att avsluta" << endl; }while(_getch() != ESC); display(p, t); delete[] p; p = NULL; return 0; } int talIn(int in) { cout << "Skriv in ett tal: "; cin >> in; cout << endl; return in; } void display(int *m, int &n) { do { for (int v =0 ; v<n ; ++v) { cout << m[v] << endl; } }while (_getch() != ESC); }

det fungera men det uppfyller inte kraven, samt att jag fick en varning om HEAP.

Permalänk
Hedersmedlem
Skrivet av Houlan:

Jag ändrade lite på koden

Det finns alltså fel i koden jag citerade. Du måste allokera nytt minne varje gång du behöver ett större fält.

Permalänk
Medlem

Det verkar som du tror att new int[i] skulle dynamiskt ändra storlek för att du senare uppdaterar i.
Isåfall har du inte förstått något om hur variabler fungerar. Du kan lika gärna skriva new int[1] och ta bort i helt.

Permalänk
Medlem

Du allokerar den dynamiskt, men den är har fortfarande en statisk mängd.

Visa signatur

Laptop - MacBook 2.0GHz, 4GB ram, Intel GMA 950
Stationär - i5 3570k @ 4ghz, 8gb ram, 120gb ssd + 2tb hdd, Windows 8 64bit, fractal design arc
Citera så jag hittar tillbaka :)

Permalänk
Medlem

Jag har test körde den senaste koden och det verka fungera.
Tex. jag matade in 555 sen 7 och 45 efter det avslutade jag med ESC, efter det så visade programmet
555
7
45
innan det avsluta. Men som sagt den uppfyller inte godkänd krav. Det måste finnas en array som alla tal ska kopiera till, så jag måste nog skapa en överförings funktion. Jag skulle blir väldig tacksamt om nån kan visa mig det.

Permalänk
Hedersmedlem
Skrivet av Houlan:

Jag har test körde den senaste koden och det verka fungera.
Tex. jag matade in 555 sen 7 och 45 efter det avslutade jag med ESC, efter det så visade programmet
555
7
45
innan det avsluta.

Om den senaste versionen är den du visade ovan så har du bara tur om det fungerar som det skall. Den enda minnesallokering du gör är
p = new int[i];
där i = 1. Alltså har du minne nog att spara ett tal. I loopen fortsätter du att spara tal trots att fältet är fullt, och om man har tur fungerar det; kanske är det ingen som använder det aktuella minnet. Risken är dock att programmet kraschar (och det är sannolikt (särskilt om du matar in många tal)).

Permalänk
Medlem
Skrivet av Elgot:

Om den senaste versionen är den du visade ovan så har du bara tur om det fungerar som det skall. Den enda minnesallokering du gör är
p = new int[i];
där i = 1. Alltså har du minne nog att spara ett tal. I loopen fortsätter du att spara tal trots att fältet är fullt, och om man har tur fungerar det; kanske är det ingen som använder det aktuella minnet. Risken är dock att programmet kraschar (och det är sannolikt (särskilt om du matar in många tal)).

Okej, jag vet att det är fel, det därför jag ber om hjälp. Någon som har en lösning?

Permalänk
Hedersmedlem
Skrivet av Houlan:

Okej, jag vet att det är fel, det därför jag ber om hjälp. Någon som har en lösning?

Om du flyttar

p = new int[i];

fyra rader nedåt kommer du reservera lagom mycket minne i varje varv. Det som då återstår är att åtgärda minnesläckan som uppstår och att kopiera de värden som finns i det gamla fältet till det nya.
Man skulle till exempel, om man även definierar p2 som en int*, kunna byta ut

p = new int[i];

mot

p2 = new int[i]; //kopiera elementen här delete[] p; p = p2;

För att kopiera elementen kan man till exempel använda en loop ungefär som i display()

Permalänk
Medlem

Tack för all hjälp, nu är det lös.