Zuweisungsproblem Pointer



  • Hallo,
    folgendes Problem:

    Ich habe in einem Struct einen Pointer auf ein 2-dim Array angelegt. Ohne eine Größe, weil die sich erst später entscheidet.
    Dann initialisiere ich in einer Funktion ein neu angelegtes Array einer bestimmten Größe. Den Pointer im struct will ich dann auf das initialisierte Array zeigen lassen. Ich kriege aber für die Zuweisung folgende Compilermeldung: "warning: assignment from incompatible pointer type"
    Weiß jemand woran das liegt?

    typedef struct
    {
      unsigned int width;
      unsigned int height;
      unsigned char **array;
    } TypePixmap;
    
    ...
    unsigned char bitmap[(inputfile->width)*3][inputfile->height];
    int count_width;
    int count_height;
    
      for(count_height = 0; count_height < inputfile->height; count_height++)
      {
        for(count_width = 0; count_width < ((inputfile->width)*3); count_width++)
    	{
    	  fscanf(input, "%c", &bitmap[count_width][count_height]);
    	}
      }
    
      inputfile->array = bitmap; //Hier kommt es zu besagter Meldung
    ...
    


  • ^^ 'TypePixmap.array' ist ein pointer auf einen pointer, 'bitmap[]' ist ein array. bei der zuweisung wird die adresse des arrays genommen, was einem einfachen pointer gleich kommt. mach aus 'TypePixmap.array' ein char* (also nur 1 sternchen), dann passt es.
    🙂



  • Meinst du so?

    typedef struct 
    { 
      unsigned int width; 
      unsigned int height; 
      unsigned char *array; 
    } TypePixmap;
    

    Dann krieg ich aber immer noch das selbe Warning.



  • absolut-c-beginner schrieb:

    Dann krieg ich aber immer noch das selbe Warning.

    ach, ich volltrottel hab' übersehen, dass du ja ein 2d-array hast. na, dann solltest du's vorher nach 'char*' casten. width und height sind ja in der struct gespeichert. char** und char[][] sind jedenfalls nicht kompatibel.
    🙂



  • ~fricky schrieb:

    char** und char[][] sind jedenfalls nicht kompatibel.
    🙂

    D.h. mein Lösungsansatz funktioniert so nicht? Und ich muss doch mit malloc und realloc und gefrickel arbeiten?



  • absolut-c-beginner schrieb:

    Und ich muss doch mit malloc und realloc und gefrickel arbeiten?

    geht auch ohne. du kannst ein 2d-array ja in ein 1d-array casten, wenn du width und height speicherst, gehen die dimensionen nicht verloren. nur mit einem 'char**' passt es nicht richtig, weil man den zwar als pointer auf ein array aus pointern nehmen kann, aber nicht als pointer auf ein 1d,2d,3d,usw. array.
    🙂



  • Ok. Wieder was gelernt...
    Aber wie genau funktioniert der cast in dem Fall? Habs so probiert; spuckt nach wie vor das Warning.

    (char *)inputfile->array = bitmap;
    


  • probier mal das, als demo sozusagen:

    #include <stdio.h>
    
    typedef struct
    {
      unsigned int width;
      unsigned int height;
      unsigned char *array;
    } TypePixmap;
    
    int main (void)
    {
      // 4*3 array mit werteb 
      char bitmap[4][3] = {{1,2,3}, {4,5,6}, {7,8,9}, {10,11,12}};
    
      // TypePix daraus machen
      TypePixmap pix;
      pix.width = 3;
      pix.height = 4;
      pix.array = (char*)bitmap;
    
      // test: array anhand von TypePix ausgeben
      {
        unsigned int x, y;
        for (y=0; y<pix.height; y++)
        {
          for (x=0; x<pix.width; x++)
          {
            printf ("%d ", pix.array[y*pix.width+x]);
          }
          puts("");
        }
      }
    }
    

    🙂



  • super! danke.



  • Ich hätte da noch eine Frage. Folgender Code:

    #include <stdio.h> 
    #include <stdlib.h>
    
    typedef struct 
    { 
      unsigned int width; 
      unsigned int height; 
      unsigned char *array; 
    } TypePixmap; 
    
    TypePixmap *test ()
    { 
      TypePixmap *pix = malloc(sizeof(TypePixmap)); 
      pix->width = 3; 
      pix->height = 4; 
    
      char bitmap[4][3] = {{1,2,3}, {4,5,6}, {7,8,9}, {10,11,12}}; 
      pix->array = (unsigned char*)bitmap; 
    
      unsigned int x, y; 
      for (y=0; y < 4; y++) 
      { 
        for (x=0; x < 3; x++) 
    	{ 
    	  printf ("%d ", pix->array[y*pix->width+x]); 
    	} 
    	puts(""); 
      } 
    
      return pix;
    }   
    
    int main ()
    {
      TypePixmap *pix = test();
      printf("\nwidth: %d\n", pix->width);
      printf("height: %d\n", pix->height);
    
      unsigned int x,y;
      for(y=0; y < 4; y++)
      {
        for(x=0; x < 3; x++)
    	{
    	  printf("%d ", pix->array[y*pix->width+x]);
    	}
    	puts("");
      }
    
      return 0;
    }
    

    Wie kann es sein, dass die Ausgabe des Arrays in der 'main' dann anders ist, als in der Funktion 'test'?

    ./a.out:

    1 2 3
    4 5 6
    7 8 9
    10 11 12

    width: 3
    height: 4
    241 31 0
    0 164 250
    0 191 9
    10 11 12



  • dein 'bitmap[4][3]' ist 'ne lokale variable. die wird 'recycled', wenn die funktion verlassen wird. du könntest z.b. mit 'malloc' speicher reservieren, der länger lebt. beispiel:

    TypePixmap *test ()
    {
      TypePixmap *pix = malloc(sizeof(TypePixmap));
      char bitmap[4][3] = {{1,2,3}, {4,5,6}, {7,8,9}, {10,11,12}};
      unsigned int x, y;
    
      pix->width = 3;
      pix->height = 4;
      pix->array = malloc (4*3);  // <-- 'nichtflüchtiger' speicher
    
      memcpy (pix->array, bitmap, 4*3);  // <-- array rueberkopieren
    
      ...
      ...
    

    🙂



  • ~fricky hat mit allem Recht, was er gesagt hat. Dein Programm sieht so aus als wenn es viel mit Speicherkrims-krams zu tun hat. Daher auch alles schön wieder mit "free" freigeben, damit du da nicht Speicherleichen hinterläßt.

    Eventuell hilft dir auch noch dieser Artikel noch, um Pointer und Pointerarithmetik, die auf dich zukommen wird, noch besser zu verstehen:
    http://www.c-plusplus.net/magazin/portal/artikel/Pointer%20in%20C(PlusPlus) Auch wird da auf Pointer auf Pointer eingegangen und auch multidimensionale Arrays besprochen.



  • ach ja, stimmt da war was...
    danke dir.



  • Es bietet sich weiterhin an, wenn du sehr viel mit Ressourcen in deinem Programm machst einen Ressourcenmanager zu programmieren, der sich um diesen Teil deines Programms autonom kümmern kann, z.b. in Spielen usw. Wenn du da weitere Informationen willst, kann ich dir da mal was zu schreiben.


Anmelden zum Antworten