2016-07-25 12 views
4

Ich könnte etwas über einige Konzepte auf Zuordner falsch verstanden haben. Aber ich weiß wirklich nicht, warum wir ein Argument von std::size_t benötigen, das an allocate übergeben wird, um die Anzahl der zuzuweisenden Objekte anzugeben. Wird das Argument verwendet, um Speicherbereiche wie Arrays oder Vektoren zuzuordnen?Wie kann der benutzerdefinierte Zuordner wissen, ob ein Zeiger auf ein Array zeigt?

Wenn sie sind, wie kann dann mein benutzerdefinierter Zuordner wissen, ob der zuvor zurückgegebene Zeiger auf eine Region oder nur auf ein Objekt zeigt? Ist mein Allokator dafür verantwortlich, diese Zeiger aufzuzeichnen?

Wenn sie nicht sind, warum brauchen wir dann dieses Argument?

+0

Hilft das? http://en.cppreference.com/w/cpp/memory/allocator/allocate – NathanOliver

Antwort

5

allocator_traits<YourAllocator<T>>::allocate wird voraussichtlich Speicher für eine zusammenhängende Folge von N Objekten des Typs T zuweisen. Das N wird durch den Parameter size_t bereitgestellt.

Wenn ja, wie kann mein benutzerdefinierter Zuordner wissen, ob der zuvor zurückgegebene Zeiger auf eine Region oder nur auf ein Objekt zeigt?

Was "zuvor zurückgegebenen Zeiger"?

Ihr Zuweiser wird informiert, wann zu reservieren und zu Speicher freigeben. Wenn die Freigabe erfolgt, it will be told what N was for the allocation that is being deallocated. Ihr Zuordner muss keine Zeiger verfolgen.

+0

Mein schlechtes, und deshalb gab es ein schreckliches Speicherleck, wenn es an STL-Container übergeben wurde. Ich habe die Signatur als 'void deallocate (Zeiger ptr, std :: size_t dummy = 1) geschrieben': - \ Thanks – YiFei

0

Angenommen, Sie sprechen hier über std :: allocator. Die Dokumentation ist ziemlich klar:

T* std::allocator::allocate(std::size_t n);

Ordnet n * sizeof (T) Bytes nicht initialisierte Speicher [...]

So ist die Antwort auf Ihre Frage wäre: Ja, Mit dem Argument werden Speicherbereiche wie Arrays oder Vektoren zugewiesen.

Und für Ihre Follow-up-Frage: Nein, müssen Sie nicht den Überblick über die zurückgegebenen Zeiger zu halten, weil std::allocator::deallocate garantiert mit der gleichen n wie std::allocator::allocate war für jede der zurückgegebenen Zeiger aufgerufen werden.

void std::allocator::deallocate(T* p, std::size_t n);

den Speicher freigibt durch den Zeiger p verwiesen, die ein Zeiger durch einen früheren Aufruf erhalten werden muss, um() zuzuteilen. Das Argument n muss gleich dem ersten Argument des Aufrufs von allocate() sein, der ursprünglich p erzeugt hat; Andernfalls ist das Verhalten nicht definiert.

+0

Ich sehe keine Garantie hier. Sie müssen den gleichen Zeiger übergeben, der mit allocate erstellt wurde, und Sie müssen die korrekte Größe übergeben, ansonsten ist es UB. – NathanOliver

+0

@NathanOliver Ich denke, sie beziehen sich auf die Garantie von Standardcontainern: Wenn Sie einen benutzerdefinierten Zuordner für 'std :: vector' erstellen, dann wird' std :: vector' immer (theoretisch) die Verträge Ihres Zuweisers respektieren und rufen "deallocate" mit demselben "p" und "n" auf wie diejenigen, die in "allocate" verwendet werden. – KABoissonneault

+0

@KABoissonneault Ah. Das macht Sinn. – NathanOliver

Verwandte Themen