In einen, mittels Pointer, relativen, addressierten, Speicher schreiben



  • hallo, bin neu hier unzwar, weil ich kein Plan habe, wie ich unter C auf inhalte unter einem Pointer zugreiffe -.-

    int DummyTex(int tex, int size, int c1, int c2) {
      fprintf(stderr, "Create Texture ... ");
      ImageMemory[tex][0] = 0;
      ImageMemory[tex][3] = malloc(size * size * sizeof(int));
      if ( ImageMemory[tex][3] == 0 ) {
        fprintf(stderr, "failed\n");
        return 0;
      } else {
        ImageMemory[tex][0] = 1;
        ImageMemory[tex][1] = size;
        ImageMemory[tex][2] = size;
        for ( int y = 0; y < size/2; y++) {
          for ( int x = 0; x < size/2 ; x++) {
            int address = ImageMemory[tex][3] + ( ImageMemory[tex][1] * y * 4 ) + ( x * 4 )
            *address = c1;
          }
        }
        ImageMemory[tex][4] = size/2;
        ImageMemory[tex][5] = size;
      return 1;
    }
    
    

    jedoch sagt er mir bei

    *address = c1;
    

    das ich einen an der Waffel habe

    textures.c:22:18: error: lvalue required as left operand of assignment
    

    was genau mache ich falsch ?

    ok, nochmal von anfang !

    ich habe unter ImageMemory[tex][3] einen Pointer auf einen mit malloc() reservierten Speicher. Dieser Speicher soll die Bildpunktdaten ( Pixel ) zu einer Textur speichern.
    Also versuche ich nun innerhalb des, mittels malloc() reservierten, speichers zuzugreiffen indem ich einen Pointer erstelle, der auf den Ort eines Pixels innerhalb des Speichers zeigt ( address ) und möchte nun den wert von c1 an die Adresse, die in "address" liegt schreiben.

    wie tue ich das ?



  • p.s.

    es geht hierbei um meine, in PureBasic geschriebene, Spiele-Engine
    https://github.com/RonnyBarthmann/ydoom
    die ich nun nach C portieren möchte
    https://github.com/RonnyBarthmann/jdoom



  • @WinSysCompany sagte in In einen, mittels Pointer, relativen, addressierten, Speicher schreiben:

    *address = c1;
    

    address ist ein int und kein pointer. Also ist da auch nix zu dereferenzieren.

    ImageMemory[ /* ... */
    

    Jedesmal wenn Du eine globale Variable verwendest, stirbt irgendo ein Kätzchen 😞

    Auch

    ImageMemory[tex][3] = malloc(size * size * sizeof(int));
    

    ist ziemlich misteriös. Was ist die Definition von ImageMemory?

    @WinSysCompany sagte in In einen, mittels Pointer, relativen, addressierten, Speicher schreiben:

    p.s.

    Das zu erwähnen ist völlig ohne Wert. Oder erwartest Du daß das jemand für dich tut?

    Wenn Du Fragen zu Deinem Code hast, solltest Du ein Minimal, Complete, and Verifiable example liefern.



  • Auch

    ImageMemory[tex][3] = malloc(size * size * sizeof(int));
    

    ist ziemlich misteriös. Was ist die Definition von ImageMemory?

    int ImageMemory[255][6];

    p.s.

    Das zu erwähnen ist völlig ohne Wert. Oder erwartest Du daß das jemand für dich tut?

    nop, war nur der Vollständigkeitshalber, soll ein Selfmade projekt werden, hab hallt nur probleme mit Pointern, da ich aus der Assemblerecke komme ^^

    Wenn Du Fragen zu Deinem Code hast, solltest Du ein Minimal, Complete, and Verifiable example liefern.

    bitte:

    
    #include <stdio.h>
    #include <stdlib.h>
    
    int ImageMemory[255][6]; // 0 = used
                            // 1 = width
                            // 2 = height
                            // 3 = memory-address
                            // 4 = x-pos of center
                            // 5 = y-pos of center
    
    int DummyTex(int tex, int size, int c1, int c2) {
      fprintf(stderr, "Create Texture ... ");
      ImageMemory[tex][0] = 0;
      ImageMemory[tex][3] = malloc(size * size * sizeof(int));
      if ( ImageMemory[tex][3] == 0 ) {
        fprintf(stderr, "failed\n");
        return 0;
      } else {
        ImageMemory[tex][0] = 1;
        ImageMemory[tex][1] = size;
        ImageMemory[tex][2] = size;
        for ( int y = 0; y < size/2; y++) {
          for ( int x = 0; x < size/2 ; x++) {
            int address = ImageMemory[tex][3] + ( ImageMemory[tex][1] * y * 4 ) + ( x * 4 )
            *address = c1;
          }
        }
        ImageMemory[tex][4] = size/2;
        ImageMemory[tex][5] = size;
      return 1;
    }
    
    


  • ImageMemory[tex][3] ist kein Pointer, sondern ein int. = malloc(size * size * sizeof(int)); macht keinen Sinn. Was willst du damit erreichen?
    Was soll DummyTex() tun?



  • DummyTex erstellt eine Dummy-Texture mit gegebener grösse "size", reserviert dafür einen speicherblock mit malloc() und Speichert die Adresse in der "Datenbank" ImageMemory[][] an der Position [i][3] wobei >i< die Texturnummer ist.
    Kann man denn ein Array mit dem Typ "Pointer" erstellen ?
    in Assembler habe ich einen Pointer immer als Int betrachtet, da er technich ein vorzeichenloser Int ist ( beide sind 32bit Breit ).
    Die Frage ist nun jedoch, wie ich C sage, das er den Int als Pointer interpretieren soll.



  • Wenn Du 255 x 6 Zeiger auf int willst:

    int* ImageMemory[255][6]

    aber das passt dann wider nicht zum Rest Deines Codes. Es scheint, daß Dir massiv die Grundlagen fehlen und Du Dich mit Deinem derzeitigen Unterfangen ein bisschen übernimmst.

    @WinSysCompany sagte in In einen, mittels Pointer, relativen, addressierten, Speicher schreiben:

    da er technich ein vorzeichenloser Int ist ( beide sind 32bit Breit ).

    Nein, das ist nichts was vom C Standart garantiert wird.

    Ein int ist ein intund ein int* ist ein pointer to int. Einfach so konvertieren zwischen beiden ist garnicht.

    Sollte man wirklich den Wert eines Pointers haben wollen:

    7.20.1.4 Integer types capable of holding object pointers

    1 The following type designates a signed integer type with the property that any valid pointer to void can be converted to this type, then converted back to pointer to void, and the result will compare equal to the original pointer:

    intptr_t
    

    The following type designates an unsigned integer type with the property that any valid pointer to void can be converted to this type, then converted back to pointer to void, and the result will compare equal to the original pointer:

    uintptr_t


  • @Swordfish sagte in In einen, mittels Pointer, relativen, addressierten, Speicher schreiben:

    da er technich ein vorzeichenloser Int ist ( beide sind 32bit Breit ).

    Nein, das ist nichts was vom C Standart garantiert wird.

    Genau, und bei modernen 64-Bit-Rechnern ist meist sizeof(int) = 4 und sizeof(int*) = 8. Es ist technisch gesehen also keineswegs immer dasselbe. Es darf allerdings dasselbe sein (der Standard verbietet nicht, dass beide dieselbe Größe haben)



  • Standartmäßig davon auszugehen ist halt in jedem Fall falsch.



  • @WinSysCompany du solltest ImageMemory nicht als 2D-Array von int definieren.
    Eher als Array von einer struct



  • @wob sagte in In einen, mittels Pointer, relativen, addressierten, Speicher schreiben:

    @Swordfish sagte in In einen, mittels Pointer, relativen, addressierten, Speicher schreiben:

    da er technich ein vorzeichenloser Int ist ( beide sind 32bit Breit ).

    Nein, das ist nichts was vom C Standart garantiert wird.

    Genau, und bei modernen 64-Bit-Rechnern ist meist sizeof(int) = 4 und sizeof(int*) = 8. Es ist technisch gesehen also keineswegs immer dasselbe. Es darf allerdings dasselbe sein (der Standard verbietet nicht, dass beide dieselbe Größe haben)

    aber das gilt doch nur, wenn ich mein Programm für 64bit compilieren würde.
    Mein Programm zielt aber nur auf die 32bit Compilierung ab, da 32bit Programme auch auf älteren Computern lauffähig sind



  • @Swordfish sagte in In einen, mittels Pointer, relativen, addressierten, Speicher schreiben:

    Standartmäßig davon auszugehen ist halt in jedem Fall falsch.

    ok, das bedenken gebe ich zu, werde noch nen if einfügen, der die versehentliche compilierung auf 64bit unterbindet, sowas wie

    if ( sizeof(int) != 4 ) { töte alles };
    


  • Wenn du ne feste breite haben willst, nutze uint8_t, int8_t, uint16_t etc.

    Meines Wissens nach garantieren dir die, dass ein uint8_t z.B. ein vorzeichenloser 8-bit integer ist.
    Wie viel bit ein int, short, long int usw. hat, ist system abhängig. Wenn es also darauf ankommt, nutze sie nicht.



  • @WinSysCompany sagte in In einen, mittels Pointer, relativen, addressierten, Speicher schreiben:

    ok, das bedenken gebe ich zu, werde noch nen if einfügen, der die versehentliche compilierung auf 64bit unterbindet, sowas wie

    if ( sizeof(int) != 4 ) { töte alles };
    

    Auf den meisten 64-Bit Systemen ist int auch weiterhin 32 Bit groß.

    Und wenn du UB (undefiniertes Verhalten) in deinem Programm hast, dann kann das „töte alles“ sowieso passieren.



  • @DirkB sagte in In einen, mittels Pointer, relativen, addressierten, Speicher schreiben:

    @WinSysCompany du solltest ImageMemory nicht als 2D-Array von int definieren.
    Eher als Array von einer struct

    danke, dass du mich auf den rechten Weg geführt hasst. ^^
    Ich muss zugeben, daran habe ich garnicht gedach:

    struct tex {
      int used;
      int width;
      int height;
      int *mem;
      int x;
      int y;
    };
    struct tex ImageMemory[255];
    
    int DummyTex(int tex, int size, int c1, int c2) {
      fprintf(stderr, "Create Texture ... ");
      ImageMemory[tex].used = 0;
      ImageMemory[tex].mem = malloc(size * size * sizeof(int));
      if ( ImageMemory[tex].mem == NULL ) {
        fprintf(stderr, "failed\n");
        return 0;
      } else {
        ImageMemory[tex].used = 1;
        ImageMemory[tex].width = size;
        ImageMemory[tex].height = size;
        for ( int y = 0; y < size/2; y++) {
          for ( int x = 0; x < size/2 ; x++) {
            int *address = ImageMemory[tex].mem;
            address + ( ImageMemory[tex].width * y * 4 );
            address + ( x * 4 );
            *address = c1;
          }
        }
        ImageMemory[tex].x = size/2;
        ImageMemory[tex].y = size;
      }
      return 1;
    };
    

    jetzt funktioniert alles, danke nochmal



  • @WinSysCompany wenn du an DummyTex jetzt noch die Adresse der struct und nicht den Index der globalen Variablen übergibst, wirst du viel flexibler in der Anwendung.

    (Du kannst auch erstmal weiterhin dein globales Array verwenden, übergibst jedoch die Adresse des Elements)



  • das Problem ist, die teile meines Programms außerhalb von texture.c sollen sich ja mit der Array nicht befassen müssen, wenn sie jedoch den Pointer liefern, mussen sie sich ja damit befassen.

    ich arbeite hallt lieber mit dem Index, da sie später in der Map-Datenstruktur auch mit ihrem Index und nicht mit der Adresse adressiert werden. die können sie dan einfach an die Befehle wie GetTexPixel() LoadTex() etc. übergeben



  • @WinSysCompany sagte in In einen, mittels Pointer, relativen, addressierten, Speicher schreiben:

        address + ( ImageMemory[tex].width * y * 4 );
        address + ( x * 4 );
    
        jetzt funktioniert alles, danke nochmal
    

    lol
    Da funktioniert überhaupt nichts.



  • @Wutz sagte in In einen, mittels Pointer, relativen, addressierten, Speicher schreiben:

    @WinSysCompany sagte in In einen, mittels Pointer, relativen, addressierten, Speicher schreiben:

        address + ( ImageMemory[tex].width * y * 4 );
        address + ( x * 4 );
    
        jetzt funktioniert alles, danke nochmal
    

    lol
    Da funktioniert überhaupt nichts.

    hab ich einen Denkfehler ?

    1. ich habe die Adresse
    2. ich erhöhe die Adresse
    3. ich schreibe c1 unter die Adresse

    oder funktioniert die Implementierung nicht ?
    der Compiler gibt mir grünes licht ...



  • @WinSysCompany schalte mal die Warnungen vom Campiler an bzw. auf höchste Stufe.

    Da kommt dann eine Warnung etwa „Ausdruck hat keinen Effekt“

    Da, wo du 2. vermutest.


Log in to reply