 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Thomas Thiele Guest
|
Posted: Wed Nov 29, 2006 3:48 pm Post subject: void-Pointer deleten |
|
|
Hallo!
Folgendes eher akademisches Problem bzw. Frage:
Irgendwo wird in Abhängigkeit von äusseren Daten ein Array dynamisch (in
Größe und Typ) erzeugt. Etwas so (stark vereinfacht):
void* ptr; //irgenwo anders
switch(Type){
case U8: ptr = static_cast<void*>(new unsigned char[SIZE]); break;
case U16: ptr = static_cast<void*>(new unsigned short[SIZE]); break;
case U32: ptr = static_cast<void*>(new unsigned int[SIZE]); break;
case F32: ptr = static_cast<void*>(new float[SIZE]); break;
}
An der Stelle, wo ich den Speicher freigeben möchte habe ich aber nur
noch den void-Pointer.
delete[] ptr;
Frage: ist garantiert dass, das klappt/nicht klappt?
Oder müsste man in dem Fall auf malloc/free zurückfallen?
Gruß Thomas |
|
| Back to top |
|
 |
Bob Hairgrove Guest
|
Posted: Wed Nov 29, 2006 8:34 pm Post subject: Re: void-Pointer deleten |
|
|
On Wed, 29 Nov 2006 10:48:36 +0100, Thomas Thiele
<thomas.thiele (AT) gmx (DOT) de> wrote:
| Quote: | Hallo!
Folgendes eher akademisches Problem bzw. Frage:
Irgendwo wird in Abhängigkeit von äusseren Daten ein Array dynamisch
(in |
| Quote: | Größe und Typ) erzeugt. Etwas so (stark vereinfacht):
void* ptr; //irgenwo anders
switch(Type){
case U8: ptr = static_cast<void*>(new unsigned char[SIZE]); break;
case U16: ptr = static_cast<void*>(new unsigned short[SIZE]);
break; |
| Quote: | case U32: ptr = static_cast<void*>(new unsigned int[SIZE]); break;
case F32: ptr = static_cast<void*>(new float[SIZE]); break;
}
An der Stelle, wo ich den Speicher freigeben möchte habe ich aber nur
noch den void-Pointer.
delete[] ptr;
Frage: ist garantiert dass, das klappt/nicht klappt?
Oder müsste man in dem Fall auf malloc/free zurückfallen?
|
Abgesehen davon, daß man in solchen Fällen eigentlich IMMER
std::vector<> vorziehen sollte, verursacht es laut C++-Standard (bei
5.3.5) undefiniertes Verhalten. Das heißt, daß ein richtiges
Funktionieren nicht garantiert ist, nachdem delete[] wie oben
aufgerufen wird. Die meisten modernen Compiler sollten es sowieso
nicht zulassen, delete[] mit einem void* aufzurufen, denn um ein Array
richtig zu deallozieren, muß die Größe eines Elements bekannt sein.
Und das kann bei void* natürlich nie der Fall sein.
Ein std::vector verhält sich genauso wie ein Array -- d.h. der
C++-Standard garantiert, daß der durch die Elemente belegte
Speicherbereich in einem einzigen Block (oder zumindest als virtueller
Block) im RAM mit aufeinanderfolgenden Elementadressen angelegt wird.
Somit kann man die Adresse des ersten Elements im vector problemlos
als Array-Anfang verwenden.
--
Bob Hairgrove
NoSpamPlease (AT) Home (DOT) com |
|
| Back to top |
|
 |
Rolf Magnus Guest
|
Posted: Wed Nov 29, 2006 8:44 pm Post subject: Re: void-Pointer deleten |
|
|
Thomas Thiele wrote:
| Quote: | Hallo!
Folgendes eher akademisches Problem bzw. Frage:
Irgendwo wird in Abhängigkeit von äusseren Daten ein Array dynamisch (in
Größe und Typ) erzeugt. Etwas so (stark vereinfacht):
void* ptr; //irgenwo anders
switch(Type){
case U8: ptr = static_cast<void*>(new unsigned char[SIZE]); break;
case U16: ptr = static_cast<void*>(new unsigned short[SIZE]); break;
case U32: ptr = static_cast<void*>(new unsigned int[SIZE]); break;
case F32: ptr = static_cast<void*>(new float[SIZE]); break;
}
An der Stelle, wo ich den Speicher freigeben möchte habe ich aber nur
noch den void-Pointer.
delete[] ptr;
Frage: ist garantiert dass, das klappt/nicht klappt?
Oder müsste man in dem Fall auf malloc/free zurückfallen?
|
Wie wäre es z.B. mit:
char* ptr; //irgenwo anders
...
case U32: ptr = new char[SIZE * sizeof(unsigned int)]; break;
...
Oder:
struct ArrayBase
{
virtual ~ArrayBase() {}
};
template <typename T, size_t S>
struct Array : public ArrayBase
{
T data[S];
};
ArrayBase* arr; //irgenwo anders
...
case U32: arr = new Array<unsigned int, SIZE>(); break;
...
Nachher reicht dann einfach ein
delete arr;
Falls SIZE keine Compilezeitkonstante sein sollte, kann man in Array
natürlich auch dynamisch mit new[] arbeiten und einen Destruktor mit
delete[] einfügen. |
|
| Back to top |
|
 |
Thomas Maeder Guest
|
Posted: Wed Nov 29, 2006 9:58 pm Post subject: Re: void-Pointer deleten |
|
|
Thomas Thiele <thomas.thiele (AT) gmx (DOT) de> writes:
| Quote: | Folgendes eher akademisches Problem bzw. Frage:
Irgendwo wird in Abhängigkeit von äusseren Daten ein Array dynamisch
(in Größe und Typ) erzeugt. Etwas so (stark vereinfacht):
void* ptr; //irgenwo anders
switch(Type){
case U8: ptr = static_cast<void*>(new unsigned char[SIZE]); break;
case U16: ptr = static_cast<void*>(new unsigned short[SIZE]); break;
case U32: ptr = static_cast<void*>(new unsigned int[SIZE]); break;
case F32: ptr = static_cast<void*>(new float[SIZE]); break;
|
Wozu die ganzen Casts?
| Quote: | }
An der Stelle, wo ich den Speicher freigeben möchte habe ich aber nur
noch den void-Pointer.
delete[] ptr;
Frage: ist garantiert dass, das klappt/nicht klappt?
|
Es ist so gut wie nie garantiert, dass etwas nicht klappt.
Die Auswertung eines delete-Ausdrucks, dessen Argument ein void-Zeiger
ist, hat aber undefiniertes Verhalten.
| Quote: | Oder müsste man in dem Fall auf malloc/free zurückfallen?
|
Zum Beispiel. Oder auf Wrapper-Klassen mit virtuellen
Destruktoren. Oder Du sorgst dafür, dass der Wert von Type dort
bekannt ist, wo delete [] gemacht wird. |
|
| Back to top |
|
 |
Thomas Thiele Guest
|
Posted: Wed Nov 29, 2006 11:53 pm Post subject: Re: void-Pointer deleten |
|
|
Rolf Magnus schrieb:
| Quote: | struct ArrayBase
{
virtual ~ArrayBase() {}
};
template <typename T, size_t S
struct Array : public ArrayBase
{
T data[S];
};
|
Diese Variante gefällt mir. std::vector ist zuviel Overhead für
Pixeldaten.
Für die eigentliche Logik wollte ich eh Templates nehmen.
Aber da wir gerade dabei sind: gibts es irgendwo eine freie Bibliothek,
die das Öffnen und Bearbeiten von Bilddateien (tiff, bmp, jpeg
etc.pp.) ermöglicht? Für Tiffs und bmp habe ich mir zwar (vor langer
Zeit) eigene Klassen geschrieben, aber bevor ich die jetzt aufbohre,
könnte man ja was (getestetes) fertiges nehmen... |
|
| Back to top |
|
 |
Thomas Thiele Guest
|
Posted: Wed Nov 29, 2006 11:57 pm Post subject: Re: void-Pointer deleten |
|
|
Thomas Maeder schrieb:
| Quote: | Die Auswertung eines delete-Ausdrucks, dessen Argument ein void-Zeiger
ist, hat aber undefiniertes Verhalten.
|
Danke, genau das wollte ich wissen.
Ich war mir da nicht sicher, weil manche Compiler vor das eigl. Array
noch Headerinfos schreiben und da der eigl. der Datentyp hervorgehen
sollte. D.h. technisch wäre das durchaus denkbar gewesen, dass es
funktioniertt. Aber wenn's undefiniert ist... |
|
| Back to top |
|
 |
Bob Hairgrove Guest
|
Posted: Thu Nov 30, 2006 10:35 pm Post subject: Re: void-Pointer deleten |
|
|
On 29 Nov 2006 09:53:42 -0800, "Thomas Thiele" <jana.luetz (AT) gmx (DOT) de>
wrote:
| Quote: | Rolf Magnus schrieb:
struct ArrayBase
{
virtual ~ArrayBase() {}
};
template <typename T, size_t S
struct Array : public ArrayBase
{
T data[S];
};
Diese Variante gefällt mir. std::vector ist zuviel Overhead für
Pixeldaten.
|
Warum denn eigentlich?
| Quote: | Für die eigentliche Logik wollte ich eh Templates nehmen.
Aber da wir gerade dabei sind: gibts es irgendwo eine freie Bibliothek,
die das Öffnen und Bearbeiten von Bilddateien (tiff, bmp, jpeg
etc.pp.) ermöglicht? Für Tiffs und bmp habe ich mir zwar (vor langer
Zeit) eigene Klassen geschrieben, aber bevor ich die jetzt aufbohre,
könnte man ja was (getestetes) fertiges nehmen...
|
Das könnte evtl. genau das Richtige sein:
http://www.paintlib.de
--
Bob Hairgrove
NoSpamPlease (AT) Home (DOT) com |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|