Funktion für Dynamische Spreicher Reservierung für zweidimensionales Array



  • Hallo zusammen,
    Ich möchte in c eine Funktion schreiben, die Speicher für ein zwei dimensionales Array reserviert,
    Ich möchte der Funktion die Anzahl der Elemente der Ersten und Zweiten Dimension übergeben und einen Pointer auf
    den Pointer-To-Pointer, für den speicher für ein zwei Dimensionales Array reserviert werden soll (Sorry, dass das schlecht formuliert ist, weiß nicht wie ich es sonst erklären soll)
    Hier ist mein Code, Doch Wenn ich das Programm starte Bricht es ab, sobald die Schleife in der Funktion 'Memory' das Zweite mal durchlaufen wird.

    Ich habe keine Ahnung was Ich falsch mache, hoffe mir kann jemand helfen.

    #include<stdio.h>
    #include<stdlib.h>
    
    typedef int** Array;
    
    void Memory(Array *Feld, int ElementeErsteDimension, int ElementeZweiteDimension){
        int i=0;
    
        *Feld=(int**)calloc(ElementeErsteDimension, sizeof(int))
    
            for(i=0;i<ElementeErsteDimension;i++){
            [I]*Feld=(int*)calloc(ElementeZweiteDimension, sizeof(int))
    
        }
    }
    
    void main(){
        Array Feld;
        Memory(&Feld,6,6);
        System("pause");
    
    }
    


  • Was soll in dem Speicher abgelegt werden, den du mit dem ersten calloc besorgst (Zeile 9)?
    Sind das wirklich int?

    Was soll das [I] in Zeile 12?
    Dein Schleifenzähler i wird klein geschrieben.

    Wenn du dir schon ein typedef machst, dann solltest du damit auch durchgehend Arbeiten. Mal Array und mal int ist verwirrend.



  • sorry, Zeile 12 ist eigentlich

    *Feld[i]=(int*)calloc(ElementeZweiteDimension, sizeof(int))
    

    Mit dem ersten calloc wird speicher für die Zeiger reserviert die auf die Elemente in der zweiten Dimension zeigen sollen.



  • Ok, nochmal anders. Wozu ist der zweite Parameter bei calloc da?



  • Der Zweite Parameter gibt an wie groß die einzelnen Elemente sind



  • Ist ein Zeiger auf int so groß wie ein int ?



  • DirkB schrieb:

    Ist ein Zeiger auf int so groß wie ein int ?

    Eigentlich auch egal, denn ein Zeiger ist kein int.
    Daher ist deine Angabe in Zeile 9 falsch.



  • Was ist denn an zeile neun falsch



  • - du willst Speicher für eine Folge von int* belegen, benutzt aber int
    - du benutzt den Deppen-Cast
    - dein Array ist kein Array
    - es gibt eine zweidim. Arrays



  • mein Array ist sehr wohl ein Array da ein Array genaugenommen aus Zeigern besteht.

    natürlich gibt es zweidimensionale Arrays, besser bekannt als Zeiger auf Zeiger.

    Wenn ich den "deppen-cast" benutze, wie würdest du denn einen void Zeiger (den calloc ja bekanntlich zurück gibt) in einen int Zeiger casten??



  • Lulle schrieb:

    mein Array ist sehr wohl ein Array da ein Array genaugenommen aus Zeigern besteht.

    Nein.
    Ein Array wird durch die Definition in Größe und Lage festgelet.
    Danach kannst du es nicht mehr ändern.
    Ein Array ist kein Pointer. Ein Pointer ist kein Array.
    Bei einem Array gibt es keine Speicherstelle, an der die Adresse abgelegt ist.

    Lulle schrieb:

    natürlich gibt es zweidimensionale Arrays, besser bekannt als Zeiger auf Zeiger.

    Ein 2D-Array ist auch nur ein zusammenhängender Speicherblock. Auch dort gibt es keine Pointer.
    Bei Zeiger auf Zeiger. hast du i.A. mehrer kleinere Speicherbereiche(die wild im Speicher verteilt sein können)

    Lulle schrieb:

    Wenn ich den "deppen-cast" benutze, wie würdest du denn einen void Zeiger (den calloc ja bekanntlich zurück gibt) in einen int Zeiger casten??

    Ein void -Pointer ist ohne cast in jeden anderen Pointer konvertierbar.
    Wenn dein Compiler einen Fehler meldet, benutzt du keinen C-Compiler.
    (Bei C++ brauchst du diesen cast)

    Das mag dir etwas spitzfindig vorkommen, ist aber so.

    Wenn du schon das typedef machst, dann nutze es auch richtig.

    ... = calloc(ElementeErsteDimension,  sizeof( *Array));
    ... = calloc(ElementeZweiteDimension, sizeof(**Array));
    

    Und schon ist das einzige int was du da hast der Schleifenzähler (und der sollte size_t sein)


  • Mod

    Lulle schrieb:

    mein Array ist sehr wohl ein Array da ein Array genaugenommen aus Zeigern besteht.

    natürlich gibt es zweidimensionale Arrays, besser bekannt als Zeiger auf Zeiger.

    Autsch! Wenn du schon andere Leute (so klugscheißerisch sie auch daher kommen mögen) korrigieren möchtest, dann sollte es wenigstens richtig sein. Dies ist genau der Punkt, den Wutz dir klarmachen wollte und wieso dein Programm nicht funktioniert: Ein Array ist kein Zeiger und ein Zeiger ist kein Array. Und ganz besonders ist ein 2D-Array (aka Array von Arrays) weder ein Array von Zeigern, noch ein Zeiger auf Arrays und ganz bestimmt kein Zeiger auf Zeiger! Und umgekehrt.

    Das ist auch keine syntaktische Spitzfindigkeit. Dahinter stehen jeweils gänzlich unterschiedliche Datenstrukturen mit vollkommen unterschiedlichen, inkompatiblen Speicherlayouts und völlig unterschiedlichen Eigenschaften.



  • Lulle schrieb:

    mein Array ist sehr wohl ein Array da ein Array genaugenommen aus Zeigern besteht.

    natürlich gibt es zweidimensionale Arrays, besser bekannt als Zeiger auf Zeiger.

    Wenn ich den "deppen-cast" benutze, wie würdest du denn einen void Zeiger (den calloc ja bekanntlich zurück gibt) in einen int Zeiger casten??

    Du hast keine Ahnung, wovon du redest.
    Ein Array ist deswegen noch lange kein Array, weil du deine Lehrvorlagen einfach nachplapperst.
    Lies im C Standard nach, was Arrays ist C sind.
    Und den Deppen-Cast benutze ich gar nicht, weil ich prinzipiell keine Zeiger-Casts benutze, da sie (im Anfängerkontext immer unnötig) und sonst nur sehr selten notwendig sind, Compilerwarnungen unterdrücken, ein "sicheres" Typkonzept vorgaukeln und nur unnötig Alignmentabhängigkeiten forcieren.

    Für deine gesuchte Funktion reicht 1x calloc, mehr brauchst du nicht:
    http://ideone.com/5O4kUl

    int main() {
    	int x, y;
    	x = 6;  /* das soll die Dynamik der Dimensionen (erst zu Laufzeit) zeigen */
    	y = 4;
    	int (*m)[x] = calloc(y,sizeof*m);
    	for(int i=0;i<y;++i)
    		for(int j=0;j<x;++j)
    			m[i][j]=i+j;
    	for(int i=0;i<y;++i,puts(""))
    		for(int j=0;j<x;++j)
    			printf("%2d",m[i][j]);
    	free(m);
    	return 0;
    }
    

    Hier ist nirgendwo ein Array vorhanden, und auch kein Cast, und trotzdem ist es ein strikt standardkonformes Programm und läuft mit jedem (C99)konformen Compiler.
    Der Gebrauch des subscript-Operators [] ist nur für Deppen gleichbedeutend mit dem Gebrauch eines Array,
    der Mehrebenen-Gebrauch [][] ist nur für Deppen gleichbedeutend mit dem Gebrauch eines zweidim. Array,
    ...


Log in to reply