2014-05-12, 01:36
  #1
Medlem
Jag har ett problem med en C++-uppgift. Jag har fyra klasser Library, Item (abstrakt basklass), Book (ärver Item) och Command. Library innehåller en dynamisk Item-array, och för varje nytt Command skickas en referens till samma Library med. Ungefär såhär (förenklat):

Kod:
// library.h

#include<item.h>
#include<book.h>

class Library
{
    public:
        Library() : size(0) {}
        ~Library() {delete[] items;}
        addBook()
        {
            Item** items2 = new Item*[size+1]
            if (numOfItems > 0)
            {
                for (int i = 0; i < size; i++)
                {
                    items2[i] = items[i]; // här!
                }
                delete[] items;
            }
            items2[size] = new Book();
            items = items2;
            size++;
        }
    private:
        Item** items;
        int size;
};

// command.h

#include<library.h>

class Command
{
    public:
        Command(Library& library) : library(library) {}
        ~Command() {}
        void doCommand()
        {
            library.addBook()
        }
    private:
        Library library;
};

// main.cpp

#include <library.h>
#include <command.h>

int main()
{
    Library* library = new Library();
    for (int i = 0; i < 50; i++)
    {
        Command* command = new Command(*library);
        command->doCommand();
    }
    return 0;
}

Första gången addBook tillkallas (genom doCommand) går allt som det ska. Andra gången däremot kraschar programmet så fort det kommer till raden markerad med "här" (i första iterationen av for-loopen). Varför händer detta, och vad kan jag göra för att förhindra det?

(och i verkligheten har Library redan en del Items innan Command-loopen i main, därför blir if-satsen i addBook sann)
Citera
2014-05-12, 05:09
  #2
Medlem
kinesarsles avatar
Den här koden går ju inte ens att kompilera.
Citera
2014-05-12, 07:28
  #3
Medlem
Om du går genom "HÄR" raden 2 gånger.. så borde du se vad som händer 2ndra varvet.

HINT: Första varvet sker följande:
items2[0] = items[0];

Men låter dig själv fundera vad som kan gå fel under 2ndra varvet..
HINT vad pekar itemsN på ? (hur stort är detta?)

Tycker din "konstruktion" och överkopiering är allmänt något som du borde fixa till:
1) Skriv den mha C++ syntax (Använda en vector)
2) Skriv den genom att använda bra C stil på minnes hantering (aka malloc + realloc)
Citera
2014-05-12, 09:14
  #4
Medlem
För att inte kopiera hela programmet hoppade jag över en del saker, bl.a. läsningen av en fil, där en del Items (närmare bestämt tio) redan har lagts till. Jag ändrar så att detta är med, och att koden går att kompilera.
Så andra gången bör items[1] peka på det andra objektet.

Anledningen till att jag använder de konstruktioner jag använder är att jag följer specifikationer för en skoluppgift.

Jag ändrade dock en sak i main-metoden, och då fungerade det bra. Så här blev den nya main-metoden:

Kod:
// main.cpp

#include <library.h>
#include <command.h>

int main()
{
    Library* library = new Library();
    for (int i = 0; i < 10; i++)
    {
        library->addBook();
    }
    Command* command = new Command(*library);
    for (int i = 0; i < 50; i++)
    {
        command->doCommand();
    }
    return 0;
}

Ändringen är alltså att en instans av Command skapas en gång, innan for-loopen, istället för att skapas för varje ny iteration av for-loopen. Så nu är det bra, men jag förstår fortfarande inte varför programmet i startinlägget kraschar.

edit: Hinner inte redigera nämnda ändringar innan min skola, ber om att få återkomma senare idag.
__________________
Senast redigerad av jaber89 2014-05-12 kl. 09:16.
Citera
2014-05-12, 09:21
  #5
Medlem
Citat:
Ursprungligen postat av jaber89
För att inte kopiera hela programmet hoppade jag över en del saker, bl.a. läsningen av en fil, där en del Items (närmare bestämt tio) redan har lagts till. Jag ändrar så att detta är med, och att koden går att kompilera.
Så andra gången bör items[1] peka på det andra objektet.

Anledningen till att jag använder de konstruktioner jag använder är att jag följer specifikationer för en skoluppgift.

Jag ändrade dock en sak i main-metoden, och då fungerade det bra. Så här blev den nya main-metoden:

Kod:
// main.cpp

#include <library.h>
#include <command.h>

int main()
{
    Library* library = new Library();
    for (int i = 0; i < 10; i++)
    {
        library->addBook();
    }
    Command* command = new Command(*library);
    for (int i = 0; i < 50; i++)
    {
        command->doCommand();
    }
    return 0;
}

Ändringen är alltså att en instans av Command skapas en gång, innan for-loopen, istället för att skapas för varje ny iteration av for-loopen. Så nu är det bra, men jag förstår fortfarande inte varför programmet i startinlägget kraschar.

edit: Hinner inte redigera nämnda ändringar innan min skola, ber om att få återkomma senare idag.

Varför använder du inte delete på objektfilen library och command i main()? Det finns ingen vits med att använda pekare till dessa objekt då det är klasser innehållande sin egen destruktor.

För övrigt skapar du en pekarlista med sixe 0+1, eller 1. Sedan av någon anledning raderar du den igen och skapar en lista igen med size 0 (inget får plats). Såklart under andra körningen får du exception. items2[size] = new Book(); <-- size = 0 i det här fallet.

Sedan är först Items2 en lista med pekare till objektet Item men sedan ändras det till book()? alltså alla pekare du nyss kopierade till item2 förloras eftersom du allokerar nytt minne med new. Vad är du försöker åstadkomma?
__________________
Senast redigerad av PG-k 2014-05-12 kl. 09:37.
Citera

Skapa ett konto eller logga in för att kommentera

Du måste vara medlem för att kunna kommentera

Skapa ett konto

Det är enkelt att registrera ett nytt konto

Bli medlem

Logga in

Har du redan ett konto? Logga in här

Logga in