Speicher allozieren



  • Ja.



  • @Iberion: Deine Ausgangslösung war teilweise richtig.

    @StupidQuestion: Wird irgendwann mal crashen.
    Schon mal die Lösung mit GCC kompiliert? MS VStudio würde höchstwahrscheinlich auch meckern.
    GCC warnung: "warning: function returns address of local variable"

    Bin der Meinung, dass die richtige Lösung so aussieht:

    #include <stdlib.h>
    
    struct IntArray
    {
      int length;
      int *field;
    };
    
    // 1.te Version
    
    struct IntArray* createIntArray (int length)
    {
      if(length < 0) {	//auch <= sinnvoll
    	return 0;	//arrays mit negativen Groessen unzulaessig
      }
    
      struct IntArray* a = (struct IntArray*) malloc(sizeof(struct IntArray));
    
      if(a != 0) {
    	  int* mem = (int*) malloc(length);
    	  if(mem == 0) {
    		  //Allokation fehlgeschlagen
                      // bereits allozierten Speicher freigeben.
    		  free((void*)a);  
    		  return 0;
    	  }
    	  //Groesse & Pointer zuweisen
    	  a->length = length;
    	  a->field = mem;
    	  return a;
      }
      //sonst Allokation fehlgeschlagen
      return 0;
    }
    
    // 2.te Version
    struct IntArray* createIntArray2 (int length)
    {
      if(length < 0) {	//auch <= sinnvoll
    	return 0;	//arrays mit negativen Groessen unzulaessig
      }
    
      int* mem = (int*) malloc(length);
      if(mem == 0) {
    	  //Allokation fehlgeschlagen
    	  return 0;
      }
      struct IntArray* a = (struct IntArray*) malloc(sizeof(struct IntArray));
    
      if(a != 0) {
    	  //Groesse & Pointer zuweisen
    	  a->length = length;
    	  a->field = mem;
    	  return a;
      }
      //Allokation fehlgeschlagen
      free( (void*) mem);// bereits allozierten Speicher freigeben.
      return 0;
    }
    
    int main (void)
    {
       struct IntArray *b;
       // b ist jetzt ein Pointer auf IRGENDWAS im Speicher
       // b kann, muss aber nicht, 0 sein
       b = createIntArray (5);
       if(b != 0) {
    	// mit b weiterarbeiten   ...
       }
       return 0;
    }
    

    Spaßeshalber 2 Versionen. Kommentare erzählen alles.
    Inkl. Null-Pointer-Überprüfungen.
    Casts nach void* eigentlich nicht notwendig.



  • dimiKL schrieb:

    @StupidQuestion: Wird irgendwann mal crashen.

    Hast du seine Kommentare mal gelesen?

    dimiKL schrieb:

    Bin der Meinung, dass die richtige Lösung so aussieht:

    Bitte cpp Tags nutzen.
    Statt int lieber size_t, dann bleibt dir auch der Test erspart. (Aber gut, war ja so vorgegeben.)
    Bei dir ist einmal der "Good-Path" und einmal der "Bad-Path" im if. Lieber einheitlich bleiben.
    Rückgabetyp von malloc musste in C nicht casten.
    Du alloziierst nur length statt length * sizeof(int) Byte!

    dimiKL schrieb:

    Casts nach void* eigentlich nicht notwendig.

    Warum machst du es dann?



  • Apropo Speicher alloziieren:
    Wie macht ihr das bei zweidimensionalen Arrays? Macht ihr für jede Zeile ein malloc? Ich habe mir angewöhnt gleich den kompletten Speicher (Zeile * Spalte) zu alloziieren und dann mit Pointer-Arithmetik zu arbeiten. Das spart die vielen Aufrufe und Modi-Wechsel.



  • Steffo schrieb:

    kompletten Speicher (Zeile * Spalte)

    Ist ja auch richtig, wie du im C++ Forum gefühlt tausendfach nachlesen kannst. 😉


  • Mod

    Steffo schrieb:

    Apropo Speicher alloziieren:
    Wie macht ihr das bei zweidimensionalen Arrays? Macht ihr für jede Zeile ein malloc?

    Das wäre kein zweidimensionales Array mehr. Man muss schon wissen, was man möchte.



  • Was bringt dir ein zweidimensionales Array außer Komfort?



  • Steffo schrieb:

    Was bringt dir ein zweidimensionales Array außer Komfort?

    Steffo schrieb:

    den kompletten Speicher (Zeile * Spalte)



  • @ccoky451: Hast recht lengthsizeif(int) müsste es heißen.
    Casts? Einfach mal zur Vermeidung von Warnungen, bin sicher, dass es Compiler gibt, die nicht automatisch " int
    " auch als " void* " akzeptieren.


  • Mod

    dimiKL schrieb:

    Casts? Einfach mal zur Vermeidung von Warnungen, bin sicher, dass es Compiler gibt, die nicht automatisch " int* " auch als " void* " akzeptieren.

    Ja, sogenannte C++-Compiler. Habe aber keine Ahnung, was dieses "C++" sein soll. Bestimmt ein Javadialekt.

    Du verhinderst also bloß, dass du Fehler bemerkst.



  • SeppJ schrieb:

    Habe aber keine Ahnung, was dieses "C++" sein soll. Bestimmt ein Javadialekt.

    Das C steht in diesem Fall für Coffee.



  • SeppJ schrieb:

    Ja, sogenannte C++-Compiler.

    Da haste nicht ordentlich gelesen SeppJ. 😉
    Jeder C und jeder C++ Compiler akzeptiert eine implizite Konvertierung von int* zu void*. Jeder C, aber kein C++ Compiler akzeptiert die implizite Konvertierung von void* zu int*. Der Microsoft C Compiler warnt bei Letzterem, was nervig ist. Aber der Cast von int* zu void* ist einfach nur Quatsch.



  • malloc in C++ !? Nötig?



  • Alles kann, nichts muss. 🤡



  • Swordfish schrieb:

    malloc in C++ !? Nötig?

    Klar, und dann gleich nen Placement new hinterher, macht das nicht jeder so? 😕



  • cooky451 schrieb:

    Swordfish schrieb:

    malloc in C++ !? Nötig?

    Klar, und dann gleich nen Placement new hinterher, macht das nicht jeder so? 😕

    Also ich verwend new...


Anmelden zum Antworten