dynamic memory.

Status
Niet open voor verdere reacties.

CanTBeaTme

Banned
Lid geworden
25 jul 2006
Berichten
235
ben wat met new en delete aant testen.

void main()
{
char **pointer;
pointer = new char *[4];
for (int x = 0; x<4; x++){
cin.getline(pointer[x],15);
}
}

deze code werkt maar bij de derde input crashed ie altijd! hoe komt dit?
 
Ok, hier is de berucht beroemde edit...

Ik heb 'm even nagemaakt met een STL string. Dit werkt wat makkelijker zonder de dubbele pointer, zodat je je beter op de new kunt concentreren.

Vergeet de delete [] niet, anders heb je een geheugenlek. Ik weet niet welk OS je gebruikt, maar onderstaande is gemaakt in Bloodshed ( GCC als compiler, WinXP als OS).

Maar goed, dat was je vraag niet:
Ik denk dat het misgaat met de declaratie: new char *[4]; De reden dat ik dat denk is omdat als je een array van chars wil aanvragen je new char [4] moet doen.
Wat er denk ik gebeurt is dat je nu geheugen aanvraagt voor een array van 4 pointers naar een char. Dat is op zich ok, maar voor de feitelijke chars vraag je geen geheugen aan. Als je dus gaat schrijven met behulp van die cin.getline is het dus ongedefinieerd wat er gebeurd.

Je kunt het oplossen zoals hier beneden, maar een type van char[15] declareren en dan new chararray [4] doen kan natuurlijk ook (denk ik, want dat heb ik nog niet geprobeerd).

Code:
#include <cstdlib>
#include <iostream>
#include <string>

using namespace std;

int main(int argc, char *argv[])
{

    string *input = new string[4];
    
    cout << "vul je 4 waarden in" << endl;
    
    for (int x = 0; x < 4; x++){
        cin >> input[x];
    }
    
    for (int x = 0; x < 4; x++){
        cout << "de waarden zijn: " << input[x] << endl;
    }
    
    delete [] input;
    
    system("PAUSE");
    return EXIT_SUCCESS;
}
 
Laatst bewerkt:
Je probeert een vrij lastig programma te schrijven. Gezien je code ga ik ervanuit dat je drie regels tekst in wilt lezen. Dat valt nog niet mee, dus ik bouw er langzaam naartoe.

Laten we beginnen met één regel tekst. Het eerste probleem waar we tegenaan lopen, is dat we moeten weten hoe lang de regel is. Dat weten we natuurlijk niet, want de regel is nog niet ingetypt, dus we gokken een maximale lengte. In jouw code heb je gekozen voor 15. Dat is wat kort, maar als het nodig is kunnen we dat later altijd aanpassen. Ik zet de maximale regellengte even in een constante, zodat we 'm makkelijk kunnen terugvinden.

Code:
const int MAXLINELENGTH = 15;

void main()
{
    char line[MAXLINELENGTH];
    cin.getline(line, MAXLINELENGTH);

    cout << line << endl;
}

Je ziet dat we (nog) geen gebruik maak van new. De variabele line kan maximaal 15 tekens bevatten. Merk op dat de gebruiker maximaal 14 tekens kan intikken (de rest wordt genegeerd). Dit komt doordat het laatste teken in een regel tekst in C++ altijd \0 is.

We hebben new pas nodig als we van tevoren niet weten hoe groot onze array moet zijn. Stel dat we aan de gebruiker vragen hoe lang een regel maximaal is, dan moeten we zijn antwoord kunnen gebruiken in plaats van MAXLINELENGTH. Daarvoor hebben we new nodig. Vergeet de delete niet aan het eind!

Code:
void main()
{
    int maxlinelength;

    cout << "Hoe lang is een regel maximaal? ";
    cin >> maxlinelength;
    cin.get();

    char* line = new char[maxlinelength];

    cin.getline(line, maxlinelength);
    cout << line << endl;
    
    delete[] line;
}

Oké, laten we nu eens drie regels inlezen. Ik begin weer even zonder new.

Code:
const int MAXLINELENGTH = 15;
const int NUMBEROFLINES = 3;

void main()
{
    char lines[MAXLINELENGTH][NUMBEROFLINES];

    for (int i = 0; i < NUMBEROFLINES; i++)
    {
        cin.getline(lines[i], MAXLINELENGTH);
        cout << lines[i] << endl;
    }
}

N.B.: Als de gebruiker een regel invoert met meer tekens dan MAXLINELENGTH - 1, dan gaat het mis bij de rest van de regels.

De variabele lines is nu een array van arrays en dat maakt het lastig als we met new gaan werken. Nu gaan we aan de gebruiker vragen hoeveel regels hij wil invoeren en hoe lang de regels moeten zijn. De variabele lines blijft een array van arrays, maar we weten de dimensies nog niet. Het type wordt dus simpelweg char**. Zodra we weten hoeveel regels de gebruiker wil invoeren, kunnen we een array maken die alle regels kan opslaan. Een regel is dan van het type char*.

Code:
char** lines = new char*[numberoflines];

Nu moeten we voor iedere regel in de array een stukje geheugen reserveren. Dit moet dus in de for-lus.

Code:
lines[i] = new char[maxlinelength];

Denk eraan dat je alle regels apart moet opruimen met delete en daarna moet je de array met regels nog eens opruimen.

Code:
for (int i = 0; i < numberoflines; i++)
{
    delete[] lines[i];
}

delete[] lines;

Het complete programma wordt als volgt.

Code:
void main()
{
    int numberoflines;
    int maxlinelength;

    cout << "Hoeveel regels wil je invoeren? ";
    cin >> numberoflines;
    cin.get();

    cout << "Hoe lang mag een regel maximaal zijn? ";
    cin >> maxlinelength;
    cin.get();

    char** lines = new char*[numberoflines];

    for (int i = 0; i < numberoflines; i++)
    {
        lines[i] = new char[maxlinelength];
        cin.getline(lines[i], maxlinelength);
        cout << lines[i] << endl;
    }

    for (int i = 0; i < numberoflines; i++)
    {
        delete[] lines[i];
    }

    delete[] lines;
}

Hopelijk maakt dit het allemaal een beetje duidelijk. Het programma is vrij lastig omdat je werkt met een array van arrays.
 
Ja ik snap het nu wel. maar ik vraag me nog altijd af waarom ie crashed, ik vermoed zo omdat ik geen lengte opgeef voor de array (maxlength) en dat ie daarom niet weet wanneer de volgende input begint.

bedankt voor de uitleg :)

en morgen ga ik naar griekeland :P;)
 
Hij crasht omdat je naar geheugen schrijft dat je niet gereserveerd hebt. Jouw aanroep van new reserveert wel vier char arrays, maar je moet de inhoud van die vier char arrays nog reserveren. Je hebt dus wel vier regels, maar die regels bevatten nog geen tekens. cin.getline doet dit niet automatisch voor je.

Veel plezier in Griekenland. :)
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan