Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Template-Problem

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 < [ 2 ]
000
28.02.2005, 19:14 Uhr
~sqrt(-1)
Gast


Was ich brauche, ist eine Template-Funktion die einen Zeiger annimmt.
Die verschiedenen Typen sind auf die der Zeiger zeigt sind z.B.:

float[3]
short
byte[4]
...

Für den ersten Typ, währe also ein Element von der Größe 3*sizeof(float).

(Die Template-Funktion muss dann noch die Byte-Offsegröße zwischen den einzelnen Elementen und die Anzahl an Elementen als Parameter annehmen.
Dann ließt die Funktion alle Elemente entsprechend des Byte-Offsets und der Anzahl in einen Puffer und speichert diese in eine Datei.)

Mein Problem ist es nun möglichst elegant die entsprechenden Zeiger zu kreieren und eine Template Funktion zu schreiben, die mit den verschiedenen Typen umgehen kann.
Damit die Template-Funktion möglichst schlank wird, möchte ich gleich mit ganzen Elementen hantieren und nicht mit einzelnen primitiven Datenelementen eines Elements.




Wenn die Struktur, worauf der Zeiger zeigt, nur einen primitiven Datentyp behinhaltet, gibt es kein Problem.
Wenn die Struktur ein Array enthält, stürzt das Programm mit dem Funktionsaufruf ab und führt nicht einmal eine Anweisung innerhalb der Template-Funktion aus.


C++:
struct _AElement
{
  short Element;
}*APointer;

struct _BElement
{
  float Element[3];
}*BPointer;

APointer = (_AElement*)VoidPointer;
LogArray(APointer, 45, 102);              // Alles Okay!

BPointer = (_BElement*)VoidPointer;
LogArray(BPointer, 55, 400);              // Absturz!

template <class ElementType> DWORD LogArray(ElementType* ArrayPointer, int ArrayStride, int ArraySize)
{
  ...
}




Wo liegt das Problem und was ist eine lauffähige Alternative?


Vielen Dank für Eure Hilfe!
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
28.02.2005, 20:01 Uhr
0xdeadbeef
Gott
(Operator)


Das hängt stark davon ab, was in der Funktion LogArray passiert.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
28.02.2005, 20:13 Uhr
~sqrt(-1)
Gast


Aber das Programm stürzt doch schon ab bevor irgend eine Anweisung in der Template-Funktion verarbeitet wird.


Falls aber dennoch relevant, hier mal ungefähr was passiert:


C++:
template <class ElementType> DWORD LogArray(ElementType* ArrayPointer, int ArrayStride, int ArraySize)
{
   ElementType ArrayBuffer[100000];

   for(int i=0; i != 100000; i++)
   {
       ArrayBuffer[i] = *(ElementType + i);
   }
}

 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
28.02.2005, 20:15 Uhr
~sqrt(-1)
Gast


ist natürlich nicht:

ArrayBuffer[i] = *(ElementType + i);

sonder:

ArrayBuffer[i] = *(ArrayPointer + i);

(habe mich nur vertippt beim schreiben des Dummy-Inhalts)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
28.02.2005, 20:17 Uhr
0xdeadbeef
Gott
(Operator)


Der Code dürfte nicht mal Kompilieren. ElementType ist ein typename, keine Variable, deswegen ist *(ElementType + i) kein sinnvoller Ausdruck.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
28.02.2005, 20:21 Uhr
~sqrt(-1)
Gast


Siehe obige Korrektur.
Ich habe es einfach nur hier ins Forum falsch eingetippt.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
28.02.2005, 20:30 Uhr
0xdeadbeef
Gott
(Operator)


OK, in dem Fall lieferts nen segfault, weil du ein Array von 45 Elementen Länge übergibst und auf die ersten 10000 Elemente zugreifst. Damit kommst du ziemlich wahrscheinlich in Speicherbereiche, die dir nicht gehören.

Übrigens, *(ArrayPointer + i) ist das selbe wie ArrayPointer[i], und zweiteres ist besser lesbar.

btw, warum benutzt du dafür nicht einfach std::copy?
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra

Dieser Post wurde am 28.02.2005 um 20:31 Uhr von 0xdeadbeef editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
28.02.2005, 20:46 Uhr
~sqrt(-1)
Gast



Zitat von 0xdeadbeef:
OK, in dem Fall lieferts nen segfault, weil du ein Array von 45 Elementen Länge übergibst und auf die ersten 10000 Elemente zugreifst.

Damit kommst du ziemlich wahrscheinlich in Speicherbereiche, die dir nicht gehören.

Übrigens, *(ArrayPointer + i) ist das selbe wie ArrayPointer[i], und zweiteres ist besser lesbar.

btw, warum benutzt du dafür nicht einfach std::copy?

Der erste Parameter ist der Byte-Offset Wert für die Elemente.
Der zweite die Elementanzahl.

Ich muss dann den ArrayPointer in einen char* casten und die Bytes hochzählen, wieder auf ElementType* casten und erst dann lese ich ein Element aus.
Das mache ich so oft, je nachdem wie gross ArraySize ist.

Aber all dies spielt doch eh keine Rolle wenn nicht einmal der erste Befehl in der Funktion verarbeitet wird.
Ich rufe die Funktion auf mit einem Pointer auf eine Struktur die ein Array beinhaltet und das Programm stürzt ab (wie oben gezeigt).
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
28.02.2005, 20:50 Uhr
0xdeadbeef
Gott
(Operator)


Naja - bei irgendeiner Anwendung muss er ja abstürzen. Befrag doch mal den Debugger deines Vertrauens; in welcher Codezeile schmiert er ab, und mit welcher Fehlermeldung?
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
28.02.2005, 20:57 Uhr
~sqrt(-1)
Gast


Dies ist eine .dll und kann daher keinen Debugger laufen lassen.
Ich kann aber von Hand debuggen und gebe als ersten Befehl in der Funktion eine Log-Zeile aus.
Tja, wenn der Typ worauf der Zeiger zeigt eine Struktur mit nur einen primitiven Datentyp als Inhalt ist, gibt es keine Probleme.
Zeigt der Zeiger jedoch auf eine Struktur mit einem Array als Inhalt, stürzt das Programm direkt mit dem Funktionsaufruf ab.
Nicht einmal die erste Zeile in der Template-Funktion wird dann verarbeitet.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 < [ 2 ]     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: