C fájlkezelés, pointerek, adattömbök

C fájlkezelés, pointerek, adattömbök
2014-04-09T10:48:15+02:00
2014-04-09T16:26:58+02:00
2022-11-30T22:00:33+01:00
MociNet
Üdv!
Régen C-ztem de már kijöttem a gyakorlatból. Most újból nekiállok, de elakadtam már az elején. Beolvasok egy fájlt és az alábbi Vertex3 struktúrából készült listát töltenék fel vele. OpenGL-es OBJ fájl minden v 1.0 2.1 3.4 egy Vector3 a normalnak és a texturának meg csak megadtam valamit egyenlőre. De mind1 most nem is ez a lényeg, hanem, hogy a Vertex3 lista idétlenül van feltöltve, de nem tudom miért. Elm mindig megfelelő mérető memoriát mallocolok, de a kimenet túl nagyokat ugrik mutatókba. Viszint ha a malloc-okat kicserélem 28-ra (sizeof(Vertex3) helyett) akkor meg jó.

Nem tudom elmondani ugy h érthető legyen, ink fordítsátok le legyetek szivesek és látni fogjátok. annyi, hogy egy olyan fájl kell hozzá ami tartalmazza a "v %f %f %f" sorokat.

Jah és tudom a lista lezárása sem stimmel de az most nem lényeg, csak az h miért nem jó a sizeof(Vertex3) malloc. Mert ha összeszámoljuk akkor (3+3+2)*4=8*4=32 bájt kell, de ha malloc(32)-t (ami ugyanaz mint a malloc(sizeof(Vertex3))) írok be akkor keverednek el az adatok. ha 28at mallocolok akkor szépen mind között 32 bájt lesz nem pedig 40. (A kimeneten ki kell vonni a hexa számokat egymásbol és megkapjuk mennyi a különbség és ez nem egyezik a log.txt-be kiirtakkal)

Köszönöm!

---------------------
typedef struct {
    float x, y, z;
} Vector3;
typedef struct {
    float x, y;
} Vector2;
typedef struct {
    Vector3 position;
    Vector3 normal;
    Vector2 texture;
} Vertex3;

Vertex3 *loadObjFile(const char*);
int bindVao0(int*, float[], GLenum, int);
void log();
void exitLog();
---------------------------
FILE *logStream;
Vertex3 *loadObjFile(const char *path) {
    FILE *fp;
    char str[128];
    char *pch;
    int counter = 0;
    Vertex3 *start, *end;
    Vertex3 *vertex3;

    log();
    fp = fopen(path,"r");
    if (fp == NULL)
        perror("Error opening file");
    else {
        vertex3 = (float*)malloc(sizeof(Vertex3)); // 28 bájttal jo lenne
        start = vertex3;
        while (fgets(str , 127 , fp) != NULL) {
            if (str[0] == 'v') {
                pch = strtok(str," ");
                pch = strtok(NULL, " ");
                vertex3->position.x = (float)atof(pch);
                pch = strtok(NULL, " ");
                vertex3->position.y = (float)atof(pch);
                pch = strtok(NULL, " ");
                vertex3->position.z = (float)atof(pch);
                vertex3->normal.x = 9; vertex3->normal.y = 9; vertex3->normal.z = 9;
                vertex3->texture.x = 8; vertex3->texture.y = 8;
                printf("%p v: %f %f %f\n", vertex3, vertex3->position.x, vertex3->position.y, vertex3->position.z);
                vertex3++;
                vertex3 = (float*)malloc(sizeof(Vertex3)); // 28 bájttal jo lenne
            }
            else
                printf("%s",str);
        }
        vertex3 = NULL;
        printf("eeeendddd%p\n", vertex3);
        fclose(fp);
        vertex3 = start;
        counter=0;
        while (vertex3 != NULL) {
            fprintf(logStream, "%p v: %f %f %f\n", vertex3, vertex3->position.x, vertex3->position.y, vertex3->position.z);
            vertex3++; counter++;
            if (getchar()=='q')
                break;
        }
    }
    exitLog();
    return vertex3;
}
void log() {
    logStream = fopen("log.txt", "w");
}
void exitLog() {
    fclose(logStream);
}
Mutasd a teljes hozzászólást!
szerinted most hogyan is foglalsz dinamikusan memóriát, azaz miként kellene a malloc-nak viselkednie?

szerintem félreérted a működését: az egymást követő hívások miért garantálnák, hogy a lefoglalt darabok egymás után fognak következni, azaz "így kapod meg őket a memóriából"?
ill. a hozzátartozó free alapján gondolhatod esetleg, hogy talán igazából nem is akkora darabot kapsz meg, mint amekkorát kértél, hanem nagyobbat, mert vélhetőleg valamennyi adminisztrációra is szükség van, hiszen a free-nek csak 1 címet adsz meg, mégis tudja valahonnan, hogy mekkora területet adsz vissza, talán ez az információ ott van valahol?, mondjuk a malloc hívás után visszakapott memóriacím előtt, hogy az egyébként ne zavarjon? ezt könnyen kiderítheted, ha utánaolvasol, vagy, ha ..., de mindegy is,

ha nem tudod, hogy mennyi vertices lesz (mert nem akarsz előreolvasni), akkor kénytelen vagy azokat vagy egy listába fűzni, vagy mondjuk a realloc-kal "átméretezned" az azok tárolására lefoglalt "területet",
nyilván ez utóbbit nem vertexenként érdemes csinálni, hanem nagyobb léptékben, azaz lépésenként mondjuk 1024 vertexnek foglalva helyet, és így csak minden 1024.-nél "átméretezni", ill. a végén, mikor kilépsz a ciklusból, hogy feleslegesen ne foglaljál memóriát,

szerkesztve: bár, ha "közben nem foglalsz máshol memóriát", akkor előfordulhat, hogy a realloc optimalizálni fog, azaz egyszerűen tudja növelni a méretet, mert van szabad hely a jelenlegi, a kibővítendő "blokk" végén, és akkor csak adminisztrálnia kell, azaz "nyugodtan" hívhatod azt vertexenként (nem fog túl sok erőforrást foglalni az "átméretezés"), ellenben viszont csak úgy tudja megoldani, hogy egy másik kezdőcímen lefoglalja az új méretnek megfelelő helyet, és a régiről átmásolja a tartalmat, majd deallokálja a régit, és visszaadja az új címet, és ez nyilván "pazarló" az erőforrásokkal,
Mutasd a teljes hozzászólást!

  • haaaajaaaaaaaj
    Kiéget ez a C. Igen nem gondoltam esetleg, hogy nem egymás után rakja. A könnyű kiderítésről meg inkább ne beszéljünk. Semmi se könnyű ami C-be van. Hiába tudod a nyelvet az implementációban/stdlibrarykban mindig vannak meglepetések. Vagy nem írják le doksiban rendesen, vagy szimplán csak azt hiszik röntgenszemem van és belátok a malloc mögé, de ha esetleg mégse akkor ott van tanuld meg az összes fv törzset. Egyébként guglizok én rendesen de már azt se tudtam mit írjak be gugliba :s
    Ezt a reallocot majd akkor megpróbálom egyenlőre hagyom érni.
    Mutasd a teljes hozzászólást!
Tetszett amit olvastál? Szeretnél a jövőben is értesülni a hasonló érdekességekről?
abcd