Hallo,
gibt es eine einfache Möglichkeit einen C++ Vector an eine Funktion zu
übergeben, die ein C Array erwartet.
So wie z.B. bei der Klasse string:
string text = "Hallo";
printf( "%s", text.c_str() );
Man kann auch text.data() machen, dann wird aber '\0' am ende
abgeschnitten und man kann den string dann nicht mehr ausgeben (weil es
ja kein C-String mehr ist).
Ich benötige das aber nicht für strings, sondern für ganz normale Arrays.
Beispiel:
vector<double> packet_lengths( total_packets );
for( pkt_num_t i=0; i
On Monday 06 October 2003 14:59, Bastian Schern wrote:
Hallo,
gibt es eine einfache Möglichkeit einen C++ Vector an eine Funktion zu übergeben, die ein C Array erwartet. [...]
Hi, das ist kein Problem, z.B. function( T* data, int size); ... std::vector<T> v; function( &v.front(), v.size()); Das setzt allerdings voraus, dass std::vector<T> intern zusammenhaengende Felder benutzt, was aber glaube ich jede Implementierung so macht. Ciao
On Monday 06 October 2003 15:31, Sebastian Huber wrote:
Das setzt allerdings voraus, dass std::vector<T> intern zusammenhaengende Felder benutzt, was aber glaube ich jede Implementierung so macht.
Das halte ich für eine sehr gewagte Annahme. Das wird früher oder später
kläglich scheitern!
Falls sich das irgendwie machen läßt, würde ich empfehlen, die Funktion so
aufzusplitten, daß sie genau ein Element bearbeitet, und dann STL-Iteratoren
benutzen - das ist die wirklich saubere Lösung.
Falls genau diese Funktion benutzt werden muß (etwa weil Sourcen nicht
verfügbar), bleibt IMHO nur, die Daten wirklich in ein neu angelegtes C-Array
umzukopieren - nicht besonders elegant oder effizient, aber sicher.
CU
--
Stefan Hundhammer
Stefan Hundhammer schrieb:
On Monday 06 October 2003 15:31, Sebastian Huber wrote:
Das setzt allerdings voraus, dass std::vector<T> intern zusammenhaengende Felder benutzt, was aber glaube ich jede Implementierung so macht.
Das halte ich für eine sehr gewagte Annahme. Das wird früher oder später kläglich scheitern!
Also so gewagt ist das nicht! Wichtige STL Implementierungen (Hewlett-Packard, ist bei MS Visual Studio 6.0 dabei; GNU + Hewlett-Packard + SGI, bei gcc 3.3) verwenden ein zusammenhaengendes Feld. Wenn die Informatiker in Zukunft nicht etwas voellig Revolutionaeres im Hinblick auf Vektorimplementierungen herausfinden, dann wird sich das auch nicht so schnell aendern. Denn warum soll man ein seit Jahren bewaertes Verfahren grundsaetzlich ueber Bord werfen?
Falls sich das irgendwie machen läßt, würde ich empfehlen, die Funktion so aufzusplitten, daß sie genau ein Element bearbeitet, und dann STL-Iteratoren benutzen - das ist die wirklich saubere Lösung.
Falls genau diese Funktion benutzt werden muß (etwa weil Sourcen nicht verfügbar), bleibt IMHO nur, die Daten wirklich in ein neu angelegtes C-Array umzukopieren - nicht besonders elegant oder effizient, aber sicher.
Da C++ so designed wurde, dass es moeglichst gut mit C Bibliotheken umgehen kann, ist es doch eigentlich nur konsequent std::vector direkt zu benutzen. Bei dem Umweg ueber Felder hat man ja wieder den ganzen Verwaltungskram am Hals. Sachen wie read( in, &v.front(), v.size()); write( out, &v.front(), v.size()); sind einfach praktisch und effizient. Ciao
On Monday 06 October 2003 17:43, Sebastian Huber wrote:
Das halte ich für eine sehr gewagte Annahme. Das wird früher oder später kläglich scheitern!
Also so gewagt ist das nicht! Wichtige STL Implementierungen (Hewlett-Packard, ist bei MS Visual Studio 6.0 dabei; GNU + Hewlett-Packard + SGI, bei gcc 3.3) verwenden ein zusammenhaengendes Feld.
Es mag wohl sein, daß die es gerade jetzt genau so tun, aber garantiert wird das nirgendwo - d.h. es ist per Definition ein Implementierungsdetail. Jede Implementierung kann das anders machen (und schon geht die Portabilität dahin), und bei jeder Version kann das anders sein - ohne jede Vorankündigung (und da kommen die Cores bei Lib-Updates). Sich auf so etwas zu verlassen, ist grob fahrlässig. Ich zumindest bin mir ziemlich sicher, daß der C++ -Standard NIRGENDS irgendwelche derartigen Zusicherungen macht.
Wenn die Informatiker in Zukunft nicht etwas voellig Revolutionaeres im Hinblick auf Vektorimplementierungen herausfinden, dann wird sich das auch nicht so schnell aendern.
So wahnsinnig revolutionär muß so etwas gar nicht sein.
Denn warum soll man ein seit Jahren bewaertes Verfahren grundsaetzlich ueber Bord werfen?
Weil es sich einfach nur auf Implementierungsdetails verläßt, die
zufälligerweise bei den verwendeten Versionen gerade so sind?
Weil man robusten, zuverlässigen Code haben will?
Weil man sich Tretminen und Zeitbomben im Code ersparen will?
CU
--
Stefan Hundhammer
On Monday 06 October 2003 17:50, Stefan Hundhammer wrote:
On Monday 06 October 2003 17:43, Sebastian Huber wrote:
Das halte ich für eine sehr gewagte Annahme. Das wird früher oder später kläglich scheitern!
Also so gewagt ist das nicht! Wichtige STL Implementierungen (Hewlett-Packard, ist bei MS Visual Studio 6.0 dabei; GNU + Hewlett-Packard + SGI, bei gcc 3.3) verwenden ein zusammenhaengendes Feld.
Es mag wohl sein, daß die es gerade jetzt genau so tun, aber garantiert wird das nirgendwo - d.h. es ist per Definition ein Implementierungsdetail.
Ja, es ist ein Implementierungsdetail, aber das "gerade jetzt" ist schlichtweg untertrieben. HP hat so um 1994 seine STL Implementierung veroeffentlicht und seitdem wird ein std::vector mit drei Zeigern (start, finish, end_of_storage) implementiert. Einfacher geht es wohl kaum, und gerade deswegen ist es ja wohl hoechst unwahrscheinlich, dass sich hier was aendern wird.
Jede Implementierung kann das anders machen (und schon geht die Portabilität dahin), und bei jeder Version kann das anders sein - ohne jede Vorankündigung (und da kommen die Cores bei Lib-Updates). Sich auf so etwas zu verlassen, ist grob fahrlässig.
Ich kann hier keine grobe Fahrlaessigkeit erkennen und bin wohl kaum der einzige, der sich in diesem Punkt darauf verlaesst.
Ich zumindest bin mir ziemlich sicher, daß der C++ -Standard NIRGENDS irgendwelche derartigen Zusicherungen macht.
Ich kenne den Standard nicht, aber wie Ralf geschrieben hat, scheint die Sache ja nicht so abwegig zu sein.
Wenn die Informatiker in Zukunft nicht etwas voellig Revolutionaeres im Hinblick auf Vektorimplementierungen herausfinden, dann wird sich das auch nicht so schnell aendern.
So wahnsinnig revolutionär muß so etwas gar nicht sein.
Doch, denn die Sparsetechniken sind ja auch schon lange bekannt, man hat sie aber nicht gewaehlt. Der std::vector ist auch nicht fuer duennbesetzte Felder da, wenn jemand so etwas hat, dann wird er wohl einen passenden Spezialcontainer suchen.
Denn warum soll man ein seit Jahren bewaertes Verfahren grundsaetzlich ueber Bord werfen?
Weil es sich einfach nur auf Implementierungsdetails verläßt, die zufälligerweise bei den verwendeten Versionen gerade so sind?
Das ist keine Antwort auf meine obige Frage, die sich auf die Implementierung von std::vector bezieht.
Weil man robusten, zuverlässigen Code haben will? Weil man sich Tretminen und Zeitbomben im Code ersparen will?
Gut, loesen wir es Britisch: We agree do disagree. Ciao Sebastian
On Monday 06 October 2003 17:43, Sebastian Huber wrote:
Da C++ so designed wurde, dass es moeglichst gut mit C Bibliotheken umgehen kann, ist es doch eigentlich nur konsequent std::vector direkt zu benutzen. Bei dem Umweg ueber Felder hat man ja wieder den ganzen Verwaltungskram am Hals. Sachen wie read( in, &v.front(), v.size()); write( out, &v.front(), v.size()); sind einfach praktisch und effizient.
Falsch: Das sind einfach tickende Zeitbomben.
Gerade, um sich solche Systemspezifika vom Hals zu halten, gibt es die C++
-Streams.
CU
--
Stefan Hundhammer
On Monday 06 October 2003 17:52, Stefan Hundhammer wrote:
On Monday 06 October 2003 17:43, Sebastian Huber wrote:
Da C++ so designed wurde, dass es moeglichst gut mit C Bibliotheken umgehen kann, ist es doch eigentlich nur konsequent std::vector direkt zu benutzen. Bei dem Umweg ueber Felder hat man ja wieder den ganzen Verwaltungskram am Hals. Sachen wie read( in, &v.front(), v.size()); write( out, &v.front(), v.size()); sind einfach praktisch und effizient.
Falsch: Das sind einfach tickende Zeitbomben.
Das sind nur dann Zeitbomben, wenn man in Zukunft std::vector anders implementiert. Das ist aber hoechst fraglich, oder nicht? Die heutigen Implementierungen sind ja auch schon ueber 10 Jahre alt und vom Prinzip her gleich geblieben (zumindest was die Speicherung als Feld angeht).
Gerade, um sich solche Systemspezifika vom Hals zu halten, gibt es die C++ -Streams.
Wir reden hier ja nicht von reiner C++ Programmierung, sondern davon, wie man eine C-Funktion, die ein Feld haben will, einfach mit einem std::vector bedient. Warum man nun ausgerechnet diese Funktion benutzen will oder muss, das ist eine ganz andere Frage.
Hi, On Mon, 6 Oct 2003, Sebastian Huber wrote:
Das sind nur dann Zeitbomben, wenn man in Zukunft std::vector anders implementiert.
Genau. Also sind es Zeitbomben.
Das ist aber hoechst fraglich, oder nicht?
Noe. Man koennte durchaus eine sparse-set Implementierung im Hintergrund von vector<T> stehen lassen ohne den generellen Fall langsamer, dafuer aber einige Spezialfaelle weniger speicherfressend zu machen.
Die heutigen Implementierungen sind ja auch schon ueber 10 Jahre alt und vom Prinzip her gleich geblieben (zumindest was die Speicherung als Feld angeht).
... was fuer die Zukunft exakt nichts besagt.
Wir reden hier ja nicht von reiner C++ Programmierung, sondern davon, wie man eine C-Funktion, die ein Feld haben will, einfach mit einem std::vector bedient.
Tja, dann verlasse man sich eben auf die Implementationdetails der STL. Das ist im Prinzip OK, wenn man dieses Requirement irgendwo gut festhaelt (eben dokumentiert). Ich will hier dann allerdings kein Herumgeheule hoeren, das dies irgendwann nicht mehr geht "obwohl es doch die letzten drei Jahre ging". Ciao, Micha.
* Am Mon, 06 Okt 2003 schrieb Sebastian Huber:
On Monday 06 October 2003 17:52, Stefan Hundhammer wrote:
On Monday 06 October 2003 17:43, Sebastian Huber wrote:
Da C++ so designed wurde, dass es moeglichst gut mit C Bibliotheken umgehen kann, ist es doch eigentlich nur konsequent std::vector direkt zu benutzen. Bei dem Umweg ueber Felder hat man ja wieder den ganzen Verwaltungskram am Hals. Sachen wie read( in, &v.front(), v.size()); write( out, &v.front(), v.size()); sind einfach praktisch und effizient.
Falsch: Das sind einfach tickende Zeitbomben.
Das sind nur dann Zeitbomben, wenn man in Zukunft std::vector anders implementiert. Das ist aber hoechst fraglich, oder nicht? Die heutigen Implementierungen sind ja auch schon ueber 10 Jahre alt und vom Prinzip her gleich geblieben (zumindest was die Speicherung als Feld angeht).
Aber bei std::vector erscheint es mir zumindest möglich, dass irgendwann einmal eine verteilte speicherung vorgenommen wird, um bei einem push_back nicht ständig die ganze Datenstruktur im Speicher verschieben zu müssen... Gruß Christoph -- Christoph Maurer - Tux#194235 - christoph-maurer at gmx.de
On Mon, 2003-10-06 at 15:40, Stefan Hundhammer wrote:
On Monday 06 October 2003 15:31, Sebastian Huber wrote:
Das setzt allerdings voraus, dass std::vector<T> intern zusammenhaengende Felder benutzt, was aber glaube ich jede Implementierung so macht.
Das halte ich für eine sehr gewagte Annahme. Das wird früher oder später kläglich scheitern!
Josuttis (The Standard C++ Library), Kap. 6.2.3: The C++ standard library does not state clearly whether the elements of a vector are required to be in congiguous memory. However, it is the intention that this is guaranteed and it will be fixed due to a defect report. Thus you can expect that for any valid index i in vector v, the following yields true: &v[i] == &v[0] + i This guarantee has some important consequences. It simply means that you can use a vector in cases in which you could use a dynamic array. For example, you can use a vector to hold data of oridinary C-strings of type char* or const char*: std::vector<char> v; v.resize(41); strcpy(&v[0],"hello, world" ); printf("%s\n", &v[0]); Ralf
participants (6)
-
Bastian Schern
-
Christoph Maurer
-
Michael Matz
-
Ralf Corsepius
-
Sebastian Huber
-
Stefan Hundhammer