Anfänger Problem(verstehe Aufgabenstellung nicht richtig)



  • Hallo,
    ich lese grade den C++ Primer Plus 6th und mein Englisch ist ein wenig schlecht bin grade im 9 Kapitel bei den Aufgaben leider gibt es keine Offizielle Lösungen und in Internet hab ich nur eine Lösung gefunden wo aber ein Kommentar drunter stand das die Aufgabe falsch ist.

    Hier die Aufgabe:

    3. Begin with the following structure declaration:
    struct chaff
    {
    char dross[20];
    int slag;
    };
    Write a program that uses placement new to place an array of two such structures in
    a buffer.Then assign values to the structure members (remembering to use
    strcpy() for the char array) and use a loop to display the contents. Option 1 is to
    use a static array, like that in Listing 9.10, for the buffer. Option 2 is to use regular
    new to allocate the buffer.

    Ausschnitt aus 9.10:

    const int BUF = 512;
    char buffer[BUF]; // chunk of memory
    
    int main(){
    ...
    pd2 = new (buffer) double[N]; // use buffer array
    ...
    return 0;
    }
    

    Ich habe jetzt einfach mal ein Programm erstellt bin mir jetzt aber nicht sicher ob es der Aufgabenstellung entspricht. Hoffe hier kann jemand besser Englisch.

    #include<iostream>
    
    using namespace std;
    
    struct chaff{ 
    	char dross[20]; 
    	int slag; 
    };
    
    char buffer[512];
    
    int main(){
    
    	int choice;
    	chaff *p_chaff;
    	char *p_buffer;
    
    	cout << "1:Static Buffer\n2:By new createt buffer\nEvery other number to quit\nEnter: ";
    
    	while(!(cin >> choice)){
    		system("cls");
    		cin.clear();
    		cin.ignore(numeric_limits<streamsize>::max(), '\n');
    		cout << "Wrong Input!!!\n1:Static Buffer\n2:By new createt buffer\nEvery other key to quit\nEnter: ";
    	}
    
    	switch(choice){
    	case 1:
    		p_chaff = new(buffer) chaff[2];
    		break;
    	case 2:
    		p_buffer = new char[512];
    		p_chaff = new(p_buffer) chaff[2];
    		break;
    	default:
    		return 0;
    		break;
    	}
    
    	strcpy_s(p_chaff[0].dross, "Object1");
    	p_chaff[0].slag = 1;
    
    	strcpy_s(p_chaff[1].dross, "Object2");
    	p_chaff[1].slag = 2;
    
    	for(int i = 0; i < 2; i++)
    		cout << &p_chaff[i] << " : " << p_chaff[i].dross << " : " << p_chaff[i].slag << endl;
    
    	cin.get();
    	cin.get();
    	return 0;
    }
    

    Verbesserung Vorschlage sind immer gerne gesehen 😃



  • Option meint: Tu es entweder auf die eine Weise oder auf die andere. Nicht auf beide. Darueber hinaus allokierst du Speicher und Objekte, gibst sie aber nicht wieder frei.


  • Mod

    placement new erfodert die Einbindung von <new>



  • Ok Danke. Das heißt ich hatte mir das mit der Abfrage sparen können und mir einfach beim Schreiben des Programm eine Art aussuchen können oder?

    @camper

    placement new erfodert die Einbindung von <new>

    Was meinst du damit?

    Geb ich den Speicher so wieder frei?

    delete [] p_buffer;
    

    Da stand nichts im Buch ob und wie man placement new frei gibt. Muss ich das überhaupt sehe da nicht so den sinn...



  • Du musst dafür sagen, dass der Destruktor der Objekte aufgerufen wird.
    Das machst du für einen Zeiger auf T wie folgt: T->~T();
    Bei deiner struct ist das jetzt nicht notwendig, weil der Destruktor nichts tut (die struct ist trivially destructible), aber generell sollte man das beachten.
    Was geleakt wird ist der Speicher vom dynamischen Array, den musst du freigeben.



  • CraftPlorer schrieb:

    @camper

    placement new erfodert die Einbindung von <new>

    Was meinst du damit?

    Die Headerdatei. Du musst #include <new> schreiben, um standardkonform zu bleiben.

    Der übliche Zyklus ist übrigens:

    void* address = operator new(elements * sizeof(T)); // rohe Speicherallokation
    new (address) T(args);                              // Konstruktion über placement new (1 Element)
    new (address) T[elements];                          // oder alternativ: Konstruktion (Array)
    ...
    T->~T();                                            // Zerstörung (bei Array in Schleife)
    operator delete(address);                           // rohe Speicherdeallokation
    

    Für die Array-Zerstörung siehe z.B. destroy_range() hier. Wikipedia hat über die ganze Thematik auch einen Artikel.



  • Ok Danke. Das macht natürlich auch mehr sinn als so ein Buffer zu erstellen. Denke das Buch wird das später auch wieder aufgreifen.
    Die einzige kleine Frage die ich noch habe ist zu dieser Zeile:

    new (address) T(args);
    

    Wofür das "(args)" ? Also was kann ich da noch machen?



  • CraftPlorer schrieb:

    Wofür das "(args)" ? Also was kann ich da noch machen?

    Ein Konstruktorargument angeben, z.B:

    new (address) std::string("foo");
    


  • Ahhh ok. Danke. Sollte mal weiter lesen war noch nicht bei Klassen und so 😃
    Muss/Kann ich den Beitrag als erledigt abstempeln oder schließen oder so was?


Anmelden zum Antworten