matrizen....



  • hi

    bin grad dabei mal wieder mit dynamischen matrizen was zu probieren, hab aber nen klitzekleines problem... das untere programm hat 2 funktionen sie sollten eigentlich auch genau das selbe machen...irgendwie funktioniert aber nur mat2(...) ich hätte es aber halt gerne ohne rückgabewert, ich hab irgendwo nen blöden denkfehler

    #include <stdio.h>
    #include <stdlib.h>
    
    void mat(int z,int s, int **mat)
    {
    	int i;
    
    	mat = malloc(z*sizeof(*mat));
    
    	for(i=0; i < z; i++)
    		mat[i]=malloc(s*sizeof(**mat));
    }
    
    int **mat2(int z, int s)
    {
    	int i;
    
    	int **mat = malloc(z*sizeof(*mat));
    
    	for(i= 0; i < z; ++i)
    	  mat[i] = malloc(s*sizeof(**mat));
    
    return mat;
    }
    
    void test(int **mat,int z, int s)
    {
    	int i,j;
    
    	for(i=0; i < z; ++i)
    	{
    		for(j=0; j < s; ++j)
            {
    
    			mat[i][j]=rand()%10;
    			printf("%d ", mat[i][j]);
    		}
     	printf("\n");
    	}
    }
    
    int main(void)
    {
    int **matrix;
    
    mat(5,5,matrix);
    //matrix = mat2(5,5);
    
    test(matrix,5,5);
    
    return 0;
    


  • der fehler in der ersten funktion liegt daran, dass du der lokalen
    zeigervariablen einen neuen wert zuweist. der zeiger ausserhalb der
    funktion kriegt das nicht mit.
    du muesstest in diesem fall einen zeiger auf die matrix uebergeben
    (ungetestet):

    void mat(int z,int s, int ***mat) 
    { 
        int i; 
    
        *mat = malloc(z*sizeof(*mat)); 
    
        for(i=0; i < z; i++) 
            (*mat[i])=malloc(s*sizeof(**mat)); 
    } 
    int main(void) 
    { 
    int **matrix; 
    
    mat(5,5,&matrix); 
    
    test(matrix,5,5); 
    
    return 0;
    


  • void foo(int* p);
    int i=3;
    int* a=&i;
    foo(a);

    p ist die Kopie des Zeigers a. a und p zeigen auf i, aber a und p sind nicht identisch, vergleiche:

    void foo(int i) { i=3; }
    int a=2;
    foo(a);

    i ist eine Kopie von a mit dem gleichen Inhalt

    Genauso ist es bei Zeigern.

    Wenn du
    *p=7;
    schreibst, ändert du auch i
    Wenn du aber
    p=malloc(sizeof(int));
    schreibst, änderst du p - und p ist eine Kopie von a. Was passiert beim Funktionsende mit der Kopie? sie verschwindet.

    Lange rede kurzer sinn - du musst einen Zeiger auf p übergeben um p ändern zu können:

    void foo(int** p) { p=malloc(sizeof(int)); p=10; }
    int i=3;
    int
    a=&i;
    foo(&a);



  • in C wird alles by value übergeben wa?

    bye

    tt



  • TheTester schrieb:

    in C wird alles by value übergeben wa?

    logisch, es gibt ja keine Referenzen.



  • hallo, ich habe diesen thread mitverfolgt und war selber erstaunt und hab mir so folgendes gedacht:

    void small(int *i) {
    	*i = malloc(50*sizeof(int));
    	printf("addr i %d\n", i);
    }
    
    int main(void) {
    	int a = 3;
    	int* a_ptr = &a;
    	printf("addr a_ptr %d\n", a_ptr);
            small(&a);
    	printf("2te addr a_ptr %d\n", a_ptr);
    
    	return 0;
    }
    

    so, bei void small(int *i) wird ja die adresse von a_ptr an den variableninhalt von i uebergeben. also greife ich ueber *i auf den inhalt von a_ptr also die adresse von a zu. mit *i = malloc.... muesste ich den variablen inhalt von a_ptr veraendern und *a_ptr duerfte dann nicht mehr auf a verweisen? ist aber so, da printf() vor und nach small() die selbe adresse angibt. woran liegt das [ja ich weiss, weil ich mich da irgendwo irre -- wo denn?]?
    oder leigt dass einfach daran, dass die anfagsadresse von i und a_ptr immer beibehalten wird. wenn ich mich recht entsinne war sizeof() von *i und *a_ptr aber auch immer gleich.

    natuerlichich haette void small(int** i) schreiben koennen -- wollte bloss ausprobieren ob das obere auch funktioniert.

    Gruss caspar

    p.s. wo gehoert nach gutem stil denn das sternchen hin? char* a oder char *a?



  • caspar
    ******

    also mein compiler schluckt den code nicht so wie er da steht 😉

    so, bei void small(int *i) wird ja die
    adresse von a_ptr an den variableninhalt
    von i uebergeben.

    small(&a);

    was du da machst is auch nich so zu empfehlen.

    Im hauptprogramm übergibst du die adresse einer "normalen" int variablen nämlich a die den Wert 3 hat.

    int a = 3;
    [...]
    small(&a);

    in der Funktion small greifst du dann auf den Wert an der Adresse von a zu mit (*i) und schreibst dort den rückgabewert von malloc hin...der ja eigentlich ein int* sein sollte...und dort meckert mein compiler 🙂 weil *i (a) ein int ist aber malloc ein int* zurückliefern sollte...ich hab jetzt malloc mal auf einen (int) umgecastet damit es funktioniert...das geht aber auch nur weil zufälligerweise auf einem 32bit system die addressen und die größe eines int's 32bit betragen...

    #include <stdio.h>
    #include <stdlib.h>
    
    void small(int *i) {
        *i = (int)malloc(50*sizeof(*i));
        printf("addr i %d\n", i);
    }
    
    int main(void) {
        int a = 3;
        int* a_ptr = &a;
    
    	printf("addresse von a  %d\n", &a);
    	printf("addr a_ptr %d\n", a_ptr);
    
    	   small(&a);
    
    	printf("wert von a %d\n", a);
    	printf("2te addr a_ptr %d\n", a_ptr);
    
        return 0;
    }
    


  • ich habe mich verschrieben: ich meinte nicht small(&a) sondern small(&a_ptr) [... bei void small(int *i) wird ja die adresse von a_ptr an den variableninhalt von i u...]
    . jetzt noch mal der code mit ein paar mehr ausgaben:

    void small(int *i) {
            printf("addr in *i vor malloc() %d\n", *i);
    	*i = malloc(50*sizeof(int));
    	printf("addr in  *i nach malloc() %d\n", *i);
    }
    int main(void) {
    	int a = 3;
    	int* a_ptr = &a;
    	printf("addr von a %d\n", &a);
    	printf("addr in  *a_ptr %d\n", a_ptr);
            small(&a_ptr);
            printf("small wurde aufgerufen\n");
            printf("addr von a %d\n", &a);
    	printf("addr in *a_ptr %d\n", a_ptr);
    	printf("*a_ptr = 4\n");
    	*a_ptr = 4;
    	printf("inhalt von a %d", a);
    
    	return 0;
    }
    

    jetzt klappt auch das, was ich in meinem ersten post schrieb:
    hier sind die ausgaben:

    addr von a -1073743676
    addr in *a_ptr -1073743676
    addr in *i vor malloc() -1073743676
    addr in *i nach malloc() 134518600
    small wurde aufgerufen
    addr von a -1073743676
    addr in *a_ptr 134518600
    *a_ptr = 4
    inhalt von a 3

    ich weiss, ich misshandle *i durch die deklaration als int [besser waehre - wie du auf TheTester geantwortet hast void small(int **i)].

    Gruss caspar



  • hmm...ich muss den malloc in der funktion noch explizit umcasten auf (int) und erhalte noch ein warning bei der parameterübergabe...aber irgendwie funktioniert es...*interessant* schon ne idee warum?

    bye

    tt



  • i bekommt die adresse von a_ptr, also i = &a_ptr. wenn du nun i dereferenzierst [oder wie man das nennt] also *i greifst du auf die speicheradresse die in i enthalten ist zu -- das ist ja die adresse von a_ptr - also der wert den a_ptr enthaelt [a_ptr enthaelt wiederrum eine adresse].



  • jaja mir ist der ablauf schon klar 🙂 aber die technik ist ja sehr fragwürdig...vor allem bei mir geht das ganze nur wenn ich die adresse die mir malloc gibt, gewaltätig auf einen int umcaste, was die sache noch fragwürdiger macht 😉 bei mir liegts echt nur am cast ist er weg kommt ein error von wegen "darf ich nicht" da das eine ein int ist und ich aber mit nem pointer, schätze mal das ist auch der ganze witz bei der sache...
    ich glaube aber sowas sollte man nicht weiter vertiefen bzw. man sollte es nicht so machen...zumal ich auch nicht weiss wie die aktion vom standard gedeckt ist (wahrscheinlich wieder nach dem motto..kann gehen muss aber nicht, da ich glaube da hier wieder die größe eines ints und die speicherbreite von 32 bit gut übereinstimmen)

    bye

    apo


Log in to reply