Größe eines Arrays feststellen
-
Hi,
also erstmal heisst es nach neuestem Standard
int main() { ... }Dann versteh ich deine Frage nicht ganz.
Üblicherweise legst du vorher die Größe eines Arrays fest, es sei denn, du willst dessen Größe dynamisch zur Laufzeit bestimmen.
Bei einer konkreteren Frage, kann man dir vielleicht eher helfen
-
void foo(double* arrDummy) { }Also man hat ja nur diese Funktion, und nun soll man feststellen, wie groß arrDummy is.
-
Hi,
also erstmal heisst es nach neuestem Standard
int main() { ... }Dann versteh ich deine Frage nicht ganz.
Üblicherweise legst du vorher die Größe eines Arrays fest, es sei denn, du willst dessen Größe dynamisch zur Laufzeit bestimmen.
Bei einer konkreteren Frage, kann man dir vielleicht eher helfen
-
Also wenn du nur einen Zeiger in der Hand hast, geht das überhaupt nicht. Da mußt du schon eine definierte Datenstruktur vorgeben, mit der du arbeiten willst (z.B. könntest du in das null-te Feld die Größe reinschreiben oder ins letzte Feld eine Endemarke setzen).
Oder du verwendest statt nackter Arrays lieber einen STL-Container (vector<> etc) - die kennen ihre Größe.PS: Eine Möglichkeit gibt es noch - du kannst dich durch die Speicherverwaltung deines Betriebssystems durchwühlen und nachsehen, wo es die Größe der reservierten Heap-Blöcke ablegt (new/delete wissen schließlich, wie groß das Array ist). Aber das ist weder portabel noch besonders komfortabel.
-
oder mache es einfach so
#define array_size(array) sizeof(array)/aizeof(array[0])müsste so klappen
-
Cefour schrieb:
oder mache es einfach so
#define array_size(array) sizeof(array)/aizeof(array[0])müsste so klappen
Solange du das Array direkt vor Ort hast, ja (siehe GPC's Beitrag) - aber wenn du nur über einen Zeiger darauf zugreifen kannst, nützt dir das gar nichts:
#define array_size(array) sizeof(array)/aizeof(array[0]) void do_something(double* data) { int size = array_size(data);//liefert Müll ... } int main() { double data[]={1,2,3,4,5}; int size = array_size(data);//hier funktioniert's do_something(data);//das bekommt nur einen Zeiger, aber keine Größenangaben ... }(und spätestens wenn du deinen Speicher mit new[] anforderst, kannst du dessen Größe überhaupt nicht mehr auf diese Weise bestimmen)
-
So wie CStoll das meinte, kommt es dem wohl am nächsten.
Mein Chef hat sowas gesagt, dass wohl intern so eine Art Markierung sein soll...
-
apo schrieb:
Mein Chef hat sowas gesagt, dass wohl intern so eine Art Markierung sein soll...
Dann hat Dein Chef unrecht. Jedenfalls ist "so eine Art Markierung" keinesfalls portabel. Es seidenn er meint nullterminierte Arrays, das soll er Dir (oder Du uns :D) dann aber auch sagen. Wobei man dann nicht mehr die Zahl 0.0 übergeben könnte.
-
apo schrieb:
Mein Chef hat sowas gesagt, dass wohl intern so eine Art Markierung sein soll...
Delphi- oder Java-geschädigt?
Du kannst std::vector<> benutzen, der speichert die Länge mit ist und wie ein Array handhabbar. Oder, wenn du die STL nicht benutzen willst, folgendes struct:template <typename T> struct array_t { int len; T *values; };Zu benutzen wie folgt:
struct array_t SomeArray; array_t.values = malloc(42); if (array_t.values) { array_t.len = 42; };Man kann sich noch Hilfsfunktionen zum Handling schreiben, oder es gleich richtig machen und Konstruktoren und Operatoren für array_t einführen, aber dann landet man am Ende bei einem nicht-standardisierten Nachbau von std::vector<>, also kann man auch gleich den benutzen.
-
apo schrieb:
void foo(double* arrDummy) { }Also man hat ja nur diese Funktion, und nun soll man feststellen, wie groß arrDummy is.
Wenn du eine Funktion wie foo hast, kannst du nicht nur nicht rausfinden, wieviele Elemente sich hinter arrDummy verbergen. Nein, es kommt noch schlimmer: du kannst nicht mal prüfen, ob arrDummy überhaupt auf ein Array verweist.
Wenn foo also nicht entweder eine bestimmte Konvention vorschreibt (z.B. wie das bei C-Strings durch die Einführung der Nullterminierung gemacht wurde) oder aber noch einen Größenparameter spendiert bekommt, kann foo nichts weiter annehmen, als dass es sich bei arrDummy um einen Zeiger auf ein double handelt.
-
HumeSikkins schrieb:
...kann foo nichts weiter annehmen, als dass es sich bei arrDummy um einen Zeiger auf ein double handelt.
noch nicht mal das...
-
net schrieb:
HumeSikkins schrieb:
...kann foo nichts weiter annehmen, als dass es sich bei arrDummy um einen Zeiger auf ein double handelt.
noch nicht mal das...
Natürlich kann ein Aufrufer auch einfach einen Nullpointer übergeben oder einen nach double*-gecastateten Zeiger auf ein Elefant-Objekt. Was ist eigentlich damit sagen wollte ist, dass die Funktion, wenn sie nicht irgendeine zusätzliche Konvention festlegt, von einem *einzelnen* Objekt (besser: 0..1) ausgehen muss, nicht von einem Array.
-
@tommie: malloc() im Zusammenhang mit C++ Klassen macht sich eher ungünstig. Wenn schon, dann solltest du lieber new nehmen, um den Speicher anzufordern.
@net:
Wobei man dann nicht mehr die Zahl 0.0 übergeben könnte.
Naja, bei einem double würde ich als Endemarke vermutlich NaN verwenden

-
HumeSikkins schrieb:
...dass die Funktion, wenn sie nicht irgendeine zusätzliche Konvention festlegt, von einem *einzelnen* Objekt (besser: 0..1) ausgehen muss, nicht von einem Array.
naja, wenn man nur den funktiosnkopf kennt: 'void blubb(double *x)' kann man eigentlich von garnix ausgehen. ist es ein array? (warum hat er denn nich x[] geschrieben?) ist es ein pointer auf ein einzelnes double? (soll das verändert werden oder wieso ist das ein pointer?). wir wissen es nicht...
-
Nein, Null-Terminiert darf das array auch nicht sein!
Aber ich muss es hier wohl nochmal deutlich sagen: Ich möchte kein vector oder sowas übergeben, eigentlich möchte ich gar nix... is nur so eine Meinungsverschiedenheit zwischen mir und meinem Chef!Und ja, mein Chef ist Java "geschädigt", denke auch das es daran liegt, dass er sich zu solchen Äußerungen hinreißen lässt.
Nächste Woche ist er wieder da, dann soll er mir zeigen, wie das gehen soll, und ich denke, dann wird auch er einsehen, dass das mit C++ einfach nciht geht.
-
CStoll schrieb:
@tommie: malloc() im Zusammenhang mit C++ Klassen macht sich eher ungünstig. Wenn schon, dann solltest du lieber new nehmen, um den Speicher anzufordern.
Stimmt prinzipiell, macht hier aber keinen Unterschied, weil ich einen Pointer initialisiert habe. Allerdings habe ich ein "*sizeof(T)" vergessen, ein weiterer Grund, warum man dafür Memberfunktionen nehmen soll, oder besser gleich std::vector<>.
-
Vor allem hast du vergessen, daß du über "T" nichts weißt - und wenn der Template-Parameter einen eigenen Konstruktor benötigt, gibt es bei nächster Gelegenheit eine mittlere Katastrophe (versuch' mal, ein Array von std::string per malloc() anzulegen UND sinnvoll damit zu arbeiten).