schützen pointer refernzen vorm trashcollector?



  • ich habe ein struct, welches so aussieht:

    struct ChainPiece
    {
        Particle par;
        ChainPiece *prev;
        ChainPiece *next;
    };
    

    jetzt erstelle ich ein anfangs und endstück:

    ChainPiece first;
    ChainPiece last;
    last.prev = &first;
    first.next = &last;
    

    jetzt erstelle ich ein zwischenelement:

    void createParticle(int x, int y, double vx, double vy, char type)
    {
        ChainPiece tmp;
        tmp.par.p.x = x;
        tmp.par.p.y = y;
        tmp.par.v.x = vx;
        tmp.par.v.y = vy;
    
    //    tmp.par.id = empty[lastEmpty];
        tmp.par.type = type;
        raster[x][y][type] = &tmp;
    	tmp.next = &last;
    	tmp.prev = last.prev;
        last.prev->next = &tmp;
        last.prev = &tmp;
    }
    

    diese zwischenelemente scheinen aber gleich nach der funktion wieder freigegeben zu werden... sprich wenn ich später in einer anderen funktion folgendes mache:

    ChainPiece *cp = first.next;
        while (cp != &last)
        {
            cp->par.p.x += cp->par.v.x;
            cp->par.p.y += cp->par.v.y;
    [...]
    

    krieg ich für den inhalt von cp nen lesefehler 😕 warum ?



  • So etwas wie einen "trashcollector" gibt es in C nicht. Es sei denn, du bindest selbst einen ein. Dann wuerdest du aber wissen, wann der was loescht.

    Wenn du wie in deinem 2. Code-Stueck einfach so im Code einer Funktion 2 Variablen festlegst, werden diese nur lokal auf dem Stack erzeugt. D.h. sobald du die Funktion verlaesst, in der du die Variablen so deklariert hast, ist auch der Stackframe und damit diese beiden Variablen hin.
    Das passiert dir z.B. nicht, wenn du die Variablen global definierst (dh. ausserhalb von Funktionen).

    Warum genau dort ein Lesefehler auftritt, kann man so nur vermuten. Poste doch mal mehr Code.



  • Nobuo T schrieb:

    So etwas wie einen "trashcollector" gibt es in C nicht. Es sei denn, du bindest selbst einen ein. Dann wuerdest du aber wissen, wann der was loescht.

    Wenn du wie in deinem 2. Code-Stueck einfach so im Code einer Funktion 2 Variablen festlegst, werden diese nur lokal auf dem Stack erzeugt. D.h. sobald du die Funktion verlaesst, in der du die Variablen so deklariert hast, ist auch der Stackframe und damit diese beiden Variablen hin.
    Das passiert dir z.B. nicht, wenn du die Variablen global definierst (dh. ausserhalb von Funktionen).

    Warum genau dort ein Lesefehler auftritt, kann man so nur vermuten. Poste doch mal mehr Code.

    nein die sind natürlich global...

    // heatparticles.cpp : Definiert den Einstiegspunkt für die Konsolenanwendung.
    //
    
    #include "stdafx.h"
    #include <time.h>
    #include <math.h>
    #include "SDL/SDL.h"
    #include <windows.h>
    const int SCREEN_WIDTH = 640;
    const int SCREEN_HEIGHT = 480;
    const int SCREEN_BPP = 32;
    const int SCREEN_FLAGS =  SDL_SWSURFACE;//|SDL_FULLSCREEN ;
    const int PCOUNT = 16000000;
    const double PI = 3.14159265;
    const double DAMPING = 1;
    const double GRAVITY = 0.0;
    const int PTYPECOUNT = 5;
    SDL_Event event;
    SDL_Surface *screen, *bscreen;
    bool quit = false;
    bool rMdown, lMdown;
    Uint32 pColors[PTYPECOUNT];
    struct Vektor
    {
        double x;
        double y;
    };
    
    struct intVektor
    {
        int x;
        int y;
    };
    struct Particle
    {
        Vektor p;
        Vektor v;
        int id;
        char type;
    };
    struct ChainPiece
    {
        Particle par;
        ChainPiece *prev;
        ChainPiece *next;
    };
    ChainPiece first;
    ChainPiece last;
    ChainPiece *raster[SCREEN_WIDTH][SCREEN_HEIGHT][PTYPECOUNT];
    
    int lastEmpty;
    intVektor mPos;
    void createParticle(int x, int y, double vx, double vy, char type)
    {
        ChainPiece tmp;
        tmp.par.p.x = x;
        tmp.par.p.y = y;
        tmp.par.v.x = vx;
        tmp.par.v.y = vy;
    
    //    tmp.par.id = empty[lastEmpty];
        tmp.par.type = type;
        raster[x][y][type] = &tmp;
    	tmp.next = &last;
    	tmp.prev = last.prev;
        last.prev->next = &tmp;
        last.prev = &tmp;
    }
    void killParticle(ChainPiece &p)
    {
    
        raster[(int)p.par.p.x][(int)p.par.p.y][p.par.type] = &first;
        p.prev->next = p.next;
        p.next->prev = p.prev;
    }
    //double pDist(int i1, int i2)
    //{
    //    return sqrt(((pList[i2].p.x-pList[i1].p.x)*(pList[i2].p.x-pList[i1].p.x)) + ((pList[i2].p.y-pList[i1].p.y)*(pList[i2].p.y-pList[i1].p.y)));
    //}
    Uint32 getpixel(SDL_Surface *surface, int x, int y)
    {
        int bpp = surface->format->BytesPerPixel;
        /* Here p is the address to the pixel we want to retrieve */
        Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
    
        switch (bpp)
        {
        case 1:
            return *p;
    
        case 2:
            return *(Uint16 *)p;
    
        case 3:
            if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
                return p[0] << 16 | p[1] << 8 | p[2];
            else
                return p[0] | p[1] << 8 | p[2] << 16;
    
        case 4:
            return *(Uint32 *)p;
    
        default:
            return 0;       /* shouldn't happen, but avoids warnings */
        }
    }
    void putpixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
    {
        int bpp = surface->format->BytesPerPixel;
        /* Here p is the address to the pixel we want to set */
        Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
    
        switch (bpp)
        {
        case 1:
            *p = pixel;
            break;
    
        case 2:
            *(Uint16 *)p = pixel;
            break;
    
        case 3:
            if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
            {
                p[0] = (pixel >> 16) & 0xff;
                p[1] = (pixel >> 8) & 0xff;
                p[2] = pixel & 0xff;
            }
            else
            {
                p[0] = pixel & 0xff;
                p[1] = (pixel >> 8) & 0xff;
                p[2] = (pixel >> 16) & 0xff;
            }
            break;
    
        case 4:
            *(Uint32 *)p = pixel;
            break;
        }
    }
    void handleInput()
    {
        while ( SDL_PollEvent( &event ) )
        {
            if ( event.type == SDL_QUIT )
            {
                //Quit the program
                quit = true;
            } 	//If a mouse button was pressed
            if ( event.type == SDL_MOUSEBUTTONDOWN )
            {
                if ( event.button.button == SDL_BUTTON_LEFT)
                {
                    lMdown = true;
                }
                if ( event.button.button == SDL_BUTTON_RIGHT)
                {
                    rMdown = true;
                }
    
            }
            else if ( event.type == SDL_MOUSEBUTTONUP )
            {
                if ( event.button.button == SDL_BUTTON_LEFT)
                {
                    lMdown = false;
                }
                if ( event.button.button == SDL_BUTTON_RIGHT)
                {
                    rMdown = false;
                }
            }
            else if ( event.type == SDL_MOUSEMOTION)
            {
                mPos.x = event.motion.x;
                mPos.y = event.motion.y;
            }
    
        }
    }
    void frame()
    {
        double xrand, yrand;
        double rad;
        double l;
        int launchspeedmax = 15;
        int launchspeedmin =2;
        ChainPiece *cp = first.next;
        while (cp != &last)
        {
            raster[(int)cp->par.p.x][(int)cp->par.p.y][cp->par.type] = &first;
            cp->par.p.x += cp->par.v.x;
            cp->par.p.y += cp->par.v.y;
            for (int i = 0; i < PTYPECOUNT; i++)
            {
                ChainPiece *op = raster[(int)cp->par.p.x][(int)cp->par.p.y][i];
    			if (cp != op && op != &first)
                {
                    if (cp->par.type == 1 && i == 0)
                    {
                        rad = rand()%360*(PI/180);
                        l = (rand()%(launchspeedmax-launchspeedmin)+launchspeedmin)/10.f;
                        xrand = sin(rad)*l;
                        yrand = cos(rad)*l;
                        createParticle(cp->par.p.x, cp->par.p.y, xrand, yrand, 1);
                        rad = rand()%360*(PI/180);
                        l = (rand()%(launchspeedmax-launchspeedmin)+launchspeedmin)/10.f;
                        xrand = sin(rad)*l;
                        yrand = cos(rad)*l;
                        createParticle(cp->par.p.x, cp->par.p.y, xrand, yrand, 1);
                        rad = rand()%360*(PI/180);
                        l = (rand()%(launchspeedmax-launchspeedmin)+launchspeedmin)/10.f;
                        xrand = sin(rad)*l;
                        yrand = cos(rad)*l;
                        createParticle(cp->par.p.x, cp->par.p.y, xrand, yrand, 1);
                        rad = rand()%360*(PI/180);
                        l = (rand()%(launchspeedmax-launchspeedmin)+launchspeedmin)/10.f;
                        xrand = sin(rad)*l;
                        yrand = cos(rad)*l;
                        createParticle(cp->par.p.x, cp->par.p.y, xrand, yrand, 1);
                        rad = rand()%360*(PI/180);
                        l = (rand()%(launchspeedmax-launchspeedmin)+launchspeedmin)/10.f;
                        xrand = sin(rad)*l;
                        yrand = cos(rad)*l;
                        createParticle(cp->par.p.x, cp->par.p.y, xrand, yrand, 1);
                        rad = rand()%360*(PI/180);
                        l = (rand()%(launchspeedmax-launchspeedmin)+launchspeedmin)/10.f;
                        xrand = sin(rad)*l;
                        yrand = cos(rad)*l;
                        createParticle(cp->par.p.x, cp->par.p.y, xrand, yrand, 1);
                        rad = rand()%360*(PI/180);
                        l = (rand()%(launchspeedmax-launchspeedmin)+launchspeedmin)/10.f;
                        xrand = sin(rad)*l;
                        yrand = cos(rad)*l;
                        createParticle(cp->par.p.x, cp->par.p.y, xrand, yrand, 1);
                        rad = rand()%360*(PI/180);
                        l = (rand()%(launchspeedmax-launchspeedmin)+launchspeedmin)/10.f;
                        xrand = sin(rad)*l;
                        yrand = cos(rad)*l;
                        createParticle(cp->par.p.x, cp->par.p.y, xrand, yrand, 1);
    
                        killParticle(*cp);
                        killParticle(*op);
                    }
                    if (cp->par.type == 1 && i == 1)
                    {
                        rad = rand()%360*(PI/180);
                        l = (rand()%(launchspeedmax-launchspeedmin)+launchspeedmin)/20.f;
                        xrand = sin(rad)*l;
                        yrand = cos(rad)*l;
                        createParticle(cp->par.p.x, cp->par.p.y, xrand, yrand, 2);
                        killParticle(*cp);
                        killParticle(*op);
                    }
                    if (cp->par.type == 2 && i == 2)
                    {
                        rad = rand()%360*(PI/180);
                        l = (rand()%(launchspeedmax-launchspeedmin)+launchspeedmin)/20.f;
                        xrand = sin(rad)*l;
                        yrand = cos(rad)*l;
                        createParticle(cp->par.p.x, cp->par.p.y, xrand, yrand, 3);
                        killParticle(*cp);
                        killParticle(*op);
                    }
                    if (cp->par.type == 3 && i == 3)
                    {
    					//rad = rand()%360*(PI/180);
    					// l = (rand()%(launchspeedmax-launchspeedmin)+launchspeedmin)/60.f;
    					// xrand = sin(rad)*l;
                        //yrand = cos(rad)*l;
                        //createParticle(cp->par.p.x, cp->par.p.y, xrand, yrand, 0);
    
                        //createParticle(cp->par.p.x, cp->par.p.y, xrand, yrand, 4);
                        killParticle(*cp);
                        killParticle(*op);
                    }
                }
            }
    
    		cp->par.v.x *= DAMPING;
    		cp->par.v.y *= DAMPING;
    		if (cp->par.p.x < 0)
    		{
    			cp->par.p.x *= -1;
    			cp->par.v.x *= -1;
    		}
    		if (cp->par.p.x > SCREEN_WIDTH-1)
    		{
    			cp->par.p.x = (SCREEN_WIDTH-1)+((SCREEN_WIDTH-1)-cp->par.p.x);
    			cp->par.v.x *= -1;
    		}
    		if (cp->par.p.y < 0)
    		{
    			cp->par.p.y *= -1;
    			cp->par.v.y *= -1;
    		}
    		if (cp->par.p.y > SCREEN_HEIGHT-1)
    		{
    			cp->par.p.y = (SCREEN_HEIGHT-1)+((SCREEN_HEIGHT-1)-cp->par.p.y);
    			cp->par.v.y *= -1;
    		}
    		raster[(int)cp->par.p.x][(int)cp->par.p.y][cp->par.type] = cp;
    		putpixel(screen,cp->par.p.x,cp->par.p.y, pColors[cp->par.type]);
    		cp = cp->next;
    	}
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        //Initialize all SDL subsystems
        if ( SDL_Init( SDL_INIT_EVERYTHING ) == -1 )
        {
            return 1;
        }
    
        //Set up the screen
        screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SCREEN_FLAGS );
        srand((unsigned)time(NULL));
    
        SDL_Rect scrRect;
        scrRect.x = 0;
        scrRect.y = 0;
        scrRect.w = SCREEN_WIDTH;
        scrRect.h = SCREEN_HEIGHT;
        pColors[0] = SDL_MapRGB(screen->format,255,255,255);
        pColors[1] = SDL_MapRGB(screen->format,255,0,0);
        pColors[2] = SDL_MapRGB(screen->format,50,50,255);
        pColors[3] = SDL_MapRGB(screen->format,50,255,50);
        pColors[4] = SDL_MapRGB(screen->format,55,55,0);
    	last.prev = &first;
    	first.next = &last;
        for ( int i=0; i < SCREEN_WIDTH; i++)
        {
            for ( int i2=0; i2 < SCREEN_HEIGHT; i2++)
            {
                for (char i3=0; i3 < PTYPECOUNT; i3++)
                    raster[i][i2][i3] = &first;
            }
        }
        for ( int i=0; i < 100; i++)
        {
            double rad = rand()%360*(PI/180);
            double l = ((rand()%4)-2.f)/8.f;
            double xrand = sin(rad)*l;
            double yrand = cos(rad)*l;
          //  createParticle(rand()%SCREEN_WIDTH, rand()%SCREEN_HEIGHT, xrand, yrand, 0);
        }
        createParticle(rand()%SCREEN_WIDTH, rand()%SCREEN_HEIGHT, (rand()%2-4)/12.f,(rand()%2-4)/12.f, 1);
    
        while (!quit)
        {
            //
    
            bscreen = SDL_ConvertSurface(screen, screen->format, SDL_SRCALPHA);
            SDL_SetAlpha(bscreen, SDL_SRCALPHA, 245);
            SDL_FillRect(screen,&scrRect,0);
            SDL_BlitSurface(bscreen, &scrRect, screen, 0);
            frame();
            if (lMdown)
            {
    
            }
            if (rMdown)
            {
    
            }
            Sleep(10);
    
            handleInput();
            if ( SDL_Flip( screen ) == -1 )
            {
                return 1;
            }
            SDL_FreeSurface(bscreen);
        }
        return 0;
    }
    

Anmelden zum Antworten