Array Größe vs Vector größe?



  • Hallo allerseits,

    jetzt habe ich hier schon eine weile im Forum herum gelesen und auch ein paar alte Beiträge gefunden, aber so recht hilft mir das alles nicht weiter.

    Ich benötige ein großes Array vom Typ short, dass so bis zu 1e7 Einträge aufnehmen kann. Wenn ich versuche so was zu machen:

    int16_t *dataArray = new int16_t[size];
    

    dann stürzt das Programm mit einem segfault ab, sofern ich über ca size=100.000 bin. Verwende ich <Vector> geht es auf einmal bis ca 1.000.000 Einträge gut, ehe das ganze abstürzt. Was macht den Vector anders? Ich dachte das ist auch nur ein Array mit Features... (?) Wenn ich richtig rechne, dann sollten das doch nur 1.000.000 * 2 byte / 1024 = 1950 kB sein. Wie kann man denn, sagen wir, 20MB Speicher anfordern? Irgendwie muss das doch gehen, sonst könnte ich auch keine Fotos mit Gimp bearbeiten...

    Wofür brauche ich das Ganze eigentlich?

    Ich habe hier ein Oszilloskop, dass ich via Software auslesen möchte. Vom Hersteller habe ich dafür ein paar Treiber und Code Schnippel erhalte, so kann man zum Beispiel mit folgendem Code die Daten aus dem Gerät auslesen:

    int16_t *dataArray = new int16_t[size];
    readparameters->dataType = int16_t;
    readparameters->dataArraSize = size;
    status = readData(readparameters,dataArray);
    

    Das heißt, ich benötige einen zusammenhängenden Block Memory der die Größe

    size*sizeof(int16_t) ~ 20MB
    

    (hier "dataArray"), in den der Treiberaufruf, der hinter readData steckt, die Daten vom Skope schaufeln kann.

    OK, Hier in Kurzform nochmals 🙂
    Warum ist Array < Vecotr was die Anzahl der Einträge angeht?
    Wie Speicher bis 20 MB anfordern?



  • Das Problem wird woanders liegen. 20 MB sind kein Problem. Ich würde außerdem zum std::vector raten, anstatt mit rohen Zeigern zu fummeln.



  • Das failt bei dir?

    using namespace std;
    char *buf = new(nothrow) char[20971520];
    if (!buf)
      cout << "fail", exit(-1);
    int i;
    cin >> i;
    cin >> buf[i];
    cout << buf[i] << endl;
    delete[] buf;
    


  • Bei mir läuft:

    #define int16_t short
    
    int main()
    {	int16_t *myArr = new int16_t[1000000];
    	delete [] myArr;
    }
    

    ohne Probleme ... (VS2008Express)



  • Hey vielen dank für die Antworten. Das ist mein Code zum testen:

    long size;
     cout << numeric_limits<size_t>::max()/sizeof(int16_t) << endl;
     size = 1000000;
     int16_t *array;
     array = new (nothrow) int16_t[size];
     if(array!=0){
       for(int16_t i = 0; i < size; i++){
         array[i] = i;
       }
       cout << "last elemet: " << array[size-1] << endl;
       delete [] array;
     }
    

    Segmentation fault in Zeile 8 sagt gdb. (Zeile 2 war nur ein Test...)

    Ich nutze den mingw Compiler von Qt 4.7.3 (akuteller QtCreator) unter Windows XP. Den code von cooky451 probiere ich mal aus, aber da sehe ich kaum einen Unterschied oder?

    @Belli:
    Nur das Anlegen und Zerstören von dem Objekt geht bei mir auch. Das Problem tritt erst beim Zugriff auf. Wenn ich das Richtig verstehe, dann macht new keine Initialisierung, es sei denn man verwendet es mit einer Klasse, bei der wird dann der Konstruktor aufgerufen. (Bitte korrigiert mich wenn ich das falsch verstanden habe)

    Ich habe irgendwo gelesen, dass man dem Combiler den die Heap Größe vorgeben muss die er Verwenden darf, stimmt das?



  • Wenn du genug Speicher am Stück frei hast, kannst du auch ein paar GB auf einmal anfordern, ist gar kein Problem. Zeig vielleicht mal mehr Code, bzw. bastel mal ein Minimalbeispiel zusammen, das den Fehler aufweist, und das wir ohne großen Aufwand kopieren und testen können.

    Ich könnte glatt vermuten, dass du beim Zusammenbasteln dieses Beispiels den Fehler findest.



  • _matze schrieb:

    Wenn du genug Speicher am Stück frei hast, kannst du auch ein paar GB auf einmal anfordern, ist gar kein Problem. Zeig vielleicht mal mehr Code, bzw. bastel mal ein Minimalbeispiel zusammen, das den Fehler aufweist, und das wir ohne großen Aufwand kopieren und testen können.

    Ich könnte glatt vermuten, dass du beim Zusammenbasteln dieses Beispiels den Fehler findest.

    Mehr als 2GB habe ich noch Frei, sagt Windows. Code -> Siehe mein letzter Post. Fehlt nur #include <iostrem>, using namespace std; und natürlich die Mainfunktion.

    @cooky451: Der code schmiert bei mir auch ab. 😞

    Kann das ein Problem von Qt sein?



  • Deine Zählvariable i ist nur 16 Bit groß, da passt der Wert von size gar nicht rein. Mach da mal ein 32 Bit Integer draus.

    EDIT: Das Problem ist hier, dass i irgendwann überläuft und negativ wird (ist ja signed). Daher versuchst du, an Stelle array[-32768] oder so zu schreiben, und das geht natürlich nicht.



  • Oh man, jetzt komm ich mir ech doof vor. Ja mit sowas wie int32_t i = 0 klappt's. Aber warum geht der code von cooky451 nicht?

    EDIT Ich sollte mir angewöhnen immer uint und co für index-variabeln zu verwenden...



  • waschbaerFurcht schrieb:

    Aber warum geht der code von cooky451 nicht?

    Der geht. "schmiert ab" reicht nicht, was genau ist denn bei dir der Fehler mit dem Code? Und hast du ihn kopiert und ohne Änderung ausprobiert?



  • _matze schrieb:

    waschbaerFurcht schrieb:

    Aber warum geht der code von cooky451 nicht?

    Der geht. "schmiert ab" reicht nicht, was genau ist denn bei dir der Fehler mit dem Code? Und hast du ihn kopiert und ohne Änderung ausprobiert?

    Naja, ich habe ihn schon ausprobiert. Sieht bei mir dann so aus:

    //using namespace std;
    char *buf = new(nothrow) char[20971520];
    if (!buf)
      cout << "fail"; 
      return -1;
    int i;
    cin >> i;
    cin >> buf[i];
    cout << buf[i] << endl;
    delete[] buf;
    

    EDIT (Der using namespace seht bei mir schon irgendwo...)

    "Schmiert ab" heißt in dem Zusammenhang, dass return -1 angesprungen wird, weil !buf == true ist. Demnach wurde buf nicht richtig initialisiert. (warum auch immer)



  • waschbaerFurcht schrieb:

    "Schmiert ab" heißt in dem Zusammenhang, dass return -1 angesprungen wird, weil !buf == true ist. Demnach wurde buf nicht richtig initialisiert. (warum auch immer)

    Nein, bei dem Code wird immer -1 zurückgegeben, wegen fehlender Klammersetzung.



  • Sorry, in meinem Code war da nur ein Komma zwischen, was zugegeben etwas schlecht "gehackt" ist. Das funktioniert mit return aber nicht, das exit() war schon Absicht 😉



  • asc schrieb:

    waschbaerFurcht schrieb:

    "Schmiert ab" heißt in dem Zusammenhang, dass return -1 angesprungen wird, weil !buf == true ist. Demnach wurde buf nicht richtig initialisiert. (warum auch immer)

    Nein, bei dem Code wird immer -1 zurückgegeben, wegen fehlender Klammersetzung.

    Oh man. Ich geht jetzt glaube ich ins Bett... Kopf->Wand.
    Vielen Dank für eure Geduld mit mir. Kann man den Thread irgendwie schließen?



  • Ich wusste schon, warum ich dich gefragt habe, ob du den Code ohne Änderungen ausprobiert hast. 😃



  • waschbaerFurcht schrieb:

    Kann man den Thread irgendwie schließen?

    Kannst du nicht und brauchst du auch nicht, passt schon. Gute Nacht! 😉 🙂



  • Kann nichts mehr dazu sagen... Versinke gerade im Boden...

    😉



  • waschbaerFurcht schrieb:

    "Schmiert ab" heißt in dem Zusammenhang, dass return -1 angesprungen wird, weil !buf == true ist. Demnach wurde buf nicht richtig initialisiert. (warum auch immer)

    So. Du hast also nicht nur gesehen, dass -1 ausgegeben wurde, sondern auch dass !buf==true ? Ich bezweifle das mal stark. Ich korrigiere deinen Satz mal so, wie du ih hättest schreiben müssen:
    ""Schmiert ab" heißt in dem Zusammenhang, dass return -1 angesprungen wird, ohne es genau zu wissen rate/schätze/vermute ich mal, weil !buf == true ist. Demnach wurde buf nicht richtig initialisiert , wenn ich richtig geraten habe. (warum auch immer)"

    waschbaerFurcht schrieb:

    Naja, ich habe ihn schon ausprobiert.

    Ausprobiert triffts. Debuggen wäre besser gewesen, dann hättest du nämlich gesehen, dass !buf durchaus nicht true war und return -1 trotzdem angesprungen wurde. Von da bis zum Erkennen des Klammerfehlers wäre es nur ein kleiner Schritt gewesen.

    Was lernen wir daraus? Nicht raten, sondern Werte im Debugger anschauen 😉



  • waschbaerFurcht schrieb:

    Kann nichts mehr dazu sagen... Versinke gerade im Boden...

    😉

    Brauchst du nicht, das sind die typischen, kleinen Fehlerchen, die wohl jedem schon mal passiert sind. Mir soll keiner erzählen, dass er noch nicht Klammern vergessen oder falsch gesetzt hat. Zumal du ja nur Code falsch geändert hast. Das ist übrigens einer der Gründe, warum ich auch einzeilige if's immer mit Klammern notiere (neben der Lesbarkeit). 🙂



  • cooky451 schrieb:

    Sorry, in meinem Code war da nur ein Komma zwischen, was zugegeben etwas schlecht "gehackt" ist. Das funktioniert mit return aber nicht, das exit() war schon Absicht 😉

    Ach, wenn man sich nur genug anstrengt, kriegt man auch Komma-Operator und return unter einen Hut 😃

    if (!buf)
      return cout << "fail", -1;
    


  • Wenn du genug Speicher am Stück frei hast, kannst du auch ein paar GB auf einmal anfordern, ist gar kein Problem. Zeig vielleicht mal mehr Code, bzw. bastel mal ein Minimalbeispiel zusammen, das den Fehler aufweist, und das wir ohne großen Aufwand kopieren und testen können.

    Es muss nicht mal ein zusammenhängender Block sein, das ist ja der Sinn von virtuellem Speicher, dass der physische Speicher fragmentiert oder sogar ausgelagert sein kann.


Anmelden zum Antworten