   cant delete sprites for my sprite class
  ok so i have this sprite class that after getting other stuff in place i started trying to make a simple game, i didn't expect to be missing anything but much to my surprise i was missing a way to get rid of the sprites, i thought ok no biggy i already have a spot for it to go, just need to use key word delete on some stuff and everything should be alright... WRONG. my program just crashes instead. here is my sprite class and class for Display information, also all other classes: #ifndef ENGINE_H_INCLUDED#define ENGINE_H_INCLUDED#include <GL/gl.h>#include <GL/glu.h>#include <GL/glut.h>#include <SDL/SDL.h>#include <SDL_opengl.h>#include <SDL_image.h>#include <SDL_mixer.h>#include <windows.h>#include <cstdio>#include <string>#include <sstream>#include <ctime>#include <cmath>#include <vector>extern "C" {    #include "lua.h"    #include "lualib.h"    #include "lauxlib.h"}using namespace std;void init();class Font {public:    string File;    GLuint Tex;    GLfloat MaxH,MaxW;    SDL_Surface* Surface;    void init(string Sfile);};class Char {public:    char Value;    GLfloat tx,ty,tw,th;    Font Bitfont;    void init(GLint sx,GLint sy,GLint sh,GLint sw, Font Sfont);    void display(GLint px, GLint py, GLfloat FontSize, GLfloat Roto);};class TextBox {public:    GLfloat x,y,theta,h,w;    Font Bitfont;};class Sound {public:    Mix_Chunk *SoundChunk;    GLint Channel;    void init(string File);    void Resume();    void Play();    void Puase();    void Stop();};class Music {public:    Mix_Music *music;    void init(string File);    void Resume();    void Play();    void Puase();    void Stop();};class SpriteDispInfo {public:    GLfloat h,w;    SDL_Surface* Temp;    GLuint Tex;    void init (string file);    void Delete();};class Sprite {public:    GLfloat rotation,x,y,w,h; // degrees    SpriteDispInfo info;    void init (SpriteDispInfo initInfo, int initialX = 0, int initialY = 0);    void display();    void kill();};bool checkCollsionBoundingBox(Sprite one, Sprite two);class Timer {private:    //The clock time when the timer started    int startTicks;    //The ticks stored when the timer was paused    int pausedTicks;    //The timer status    bool paused;    bool started;public:    //Initializes variables    Timer();    //The various clock actions    void start();    void stop();    void pause();    void unpause();    //Gets the timer's time    int get_ticks();    //Checks the status of the timer    bool is_started();    bool is_paused();};#endif // ENGINE_H_INCLUDEDhere are there related functions #include <Engine.h>const float pi = 3.1415926535897932384626433832795;SDL_Surface* screen = NULL;int FRAMES_PER_SECOND;bool init_GL() {    //Set clear color    glClearColor( 1, 0, 0, 1 );    glEnable( GL_TEXTURE_2D );    glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);    glEnable(GL_BLEND);    glMatrixMode( GL_PROJECTION );    glLoadIdentity();    glOrtho( 0, glutGet(GLUT_SCREEN_WIDTH), glutGet(GLUT_SCREEN_HEIGHT), 0, -1, 1 );    //Initialize modelview matrix    glMatrixMode( GL_MODELVIEW );    glLoadIdentity();    //If there was any errors    if ( glGetError() != GL_NO_ERROR ) {   return false;    }    //If everything initialized    return true;}int init_sdl() {    ShowCursor(false);    SDL_Init (SDL_INIT_VIDEO | SDL_INIT_AUDIO);    SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );    Mix_OpenAudio(22050, AUDIO_S16, 2, 4096);    SDL_WM_SetCaption ("Juice", NULL);    screen = SDL_SetVideoMode (glutGet(GLUT_SCREEN_WIDTH),glutGet(GLUT_SCREEN_HEIGHT), 32, SDL_OPENGL|SDL_FULLSCREEN);    FRAMES_PER_SECOND = 1;}void init() {    init_sdl();    init_GL();}GLuint ConvertSDL_SurfaceToOpenGLTex( GLuint texture,SDL_Surface *surface, GLenum texture_format, GLint nOfColors) {    if (surface) {// Check that the image's width is a power of 2   if ( (surface->w & (surface->w - 1)) != 0 ) {  printf("warning: image's width is not a power of 2\n");   }   // Also check if the height is a power of 2   if ( (surface->h & (surface->h - 1)) != 0 ) {  printf("warning: image's height is not a power of 2\n");   }   // get the number of channels in the SDL surface   nOfColors = surface->format->BytesPerPixel;   if (nOfColors == 4) {   // contains an alpha channel  if (surface->format->Rmask == 0x000000ff) texture_format = GL_RGBA;  else texture_format = GL_BGRA;   } else if (nOfColors == 3) {   // no alpha channel  if (surface->format->Rmask == 0x000000ff) texture_format = GL_RGB;  else texture_format = GL_BGR;   } else {  printf("warning: the image is not truecolor..  this will probably break\n");  // this error should not go unhandled   }   // Have OpenGL generate a texture object handle for us   glGenTextures( 1, &texture );   // Bind the texture object   glBindTexture( GL_TEXTURE_2D, texture );   // Set the texture's stretching properties   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );   // Edit the texture object's image data using the information SDL_Surface gives us   glTexImage2D( GL_TEXTURE_2D, 0, nOfColors, surface->w, surface->h, 0,  texture_format, GL_UNSIGNED_BYTE, surface->pixels );   return texture;   printf("SDL could not load image.bmp: %s\n", SDL_GetError());   SDL_Quit();   return 1;    } else {// Free the SDL_Surface only if it was successfully created   SDL_FreeSurface( surface );    }}SDL_Surface *load_image (std::string filename) {    //The image that's loaded    SDL_Surface* loadedImage = NULL;    //The optimized surface that will be used    SDL_Surface* optimizedImage = NULL;    //Load the image    loadedImage = IMG_Load (filename.c_str());    //If the image loaded    if (loadedImage != NULL) {   //Create an optimized surface   optimizedImage =   SDL_DisplayFormatAlpha (loadedImage);   //Free the old surface   SDL_FreeSurface (loadedImage);   //If the surface was optimized   if (optimizedImage != NULL) {  //Color key surface   }    }    //Return the optimized surface    return optimizedImage;}void apply_surface (int x, int y, SDL_Surface* source, SDL_Surface* destination, SDL_Rect* clip = NULL) {    //Holds offsets    SDL_Rect offset;    //Get offsets    offset.x = x;    offset.y = y;    //Blit    SDL_BlitSurface (source, clip, destination, &offset);}Timer::Timer() {    //Initialize the variables    startTicks = 0;    pausedTicks = 0;    paused = false;    started = false;}void Timer::start() {    //Start the timer    started = true;    //Unpause the timer    paused = false;    //Get the current clock time    startTicks = SDL_GetTicks();}void Timer::stop() {    //Stop the timer    started = false;    //Unpause the timer    paused = false;}void Timer::pause() {    //If the timer is running and isn't already paused    if ( (started == true) && (paused == false)) {   //Pause the timer   paused = true;   //Calculate the paused ticks   pausedTicks = SDL_GetTicks() - startTicks;    }}void Timer::unpause() {    //If the timer is paused    if (paused == true) {   //Unpause the timer   paused = false;   //Reset the starting ticks   startTicks = SDL_GetTicks() - pausedTicks;   //Reset the paused ticks   pausedTicks = 0;    }}int Timer::get_ticks() {    //If the timer is running    if (started == true) {   //If the timer is paused   if (paused == true) {  //Return the number of ticks when the timer was paused  return pausedTicks;   } else {  //Return the current time minus the start time  return SDL_GetTicks() - startTicks;   }    }    //If the timer isn't running    return 0;}bool Timer::is_started() {    return started;}bool Timer::is_paused() {    return paused;}void SpriteDispInfo::init (string file) {    Temp = load_image (file);    Tex = ConvertSDL_SurfaceToOpenGLTex(Tex,Temp,GL_RGBA,4);    h = Temp->h;    w = Temp->w;    SDL_FreeSurface (Temp);}void SpriteDispInfo::Delete() {    delete &Temp;    delete &Tex;    delete &h;    delete &w;}void Sprite::init (SpriteDispInfo initInfo, int initialX, int initialY) {    x = initialX;    y = initialY;    rotation = 0;    info = initInfo;    w = info.w;    h = info.h;}void Sprite::kill() {   delete &x;   delete &y;   delete &rotation;   delete &w;   delete &h;   info.Delete();   delete &info;}void Sprite::display() {    glBindTexture( GL_TEXTURE_2D, info.Tex);    glPushMatrix();    glTranslatef(x+(w/2),y+(h/2),0);    glRotatef(rotation, 0, 0, 1);    glTranslatef(-x-(h/2),-y-(h/2),0);    glBegin( GL_QUADS );    //Bottom-left vertex (corner)    glTexCoord2f( 0, 0 );    glVertex2f( x, y);    //Bottom-right vertex (corner)    glTexCoord2f( 0, 1 );    glVertex2f( x, y+h);    //Top-right vertex (corner)    glTexCoord2f( 1, 1 );    glVertex2f( x+w, y+h);    //Top-left vertex (corner)    glTexCoord2f( 1, 0 );    glVertex2f(x+w, y);    glEnd();    glPopMatrix();    glLoadIdentity();}void Music::init(string File) {    music = Mix_LoadMUS(File.c_str());}void Music::Play() {    Mix_PlayMusic(music, 0);}void Music::Puase() {    Mix_PauseMusic();}void Music::Resume() {    Mix_ResumeMusic();}void Music::Stop() {    Mix_HaltMusic();}void Sound::init(string File) {    SoundChunk = Mix_LoadWAV(File.c_str());}void Sound::Play() {    Channel = Mix_PlayChannel(-1,SoundChunk,0);}void Sound::Stop() {    Mix_HaltChannel(Channel);}void Sound::Puase() {    Mix_Pause(Channel);}void Sound::Resume() {    Mix_Resume(Channel);}bool checkCollsionBoundingBox(Sprite A, Sprite B) {    int leftA, leftB;    int rightA, rightB;    int topA, topB;    int bottomA, bottomB;    //Calculate the sides of rect A    leftA = A.x;    rightA = A.x + A.w;    topA = A.y;    bottomA = A.y + A.h;    //Calculate the sides of rect B    leftB = B.x;    rightB = B.x + B.w;    topB = B.y;    bottomB = B.y + B.h;    //If any of the sides from A are outside of B    if( bottomA <= topB )    {   return false;    }    if( topA >= bottomB )    {   return false;    }    if( rightA <= leftB )    {   return false;    }    if( leftA >= rightB )    {   return false;    }    //If none of the sides from A are outside B    return true;}void Font::init(string Sfile) {    Surface = load_image (Sfile);    MaxH = Surface->h;    MaxW = Surface->w;    Tex = ConvertSDL_SurfaceToOpenGLTex(Tex,Surface,GL_RGBA,4);    SDL_FreeSurface (Surface);}void Char::init(GLint sx,GLint sy,GLint sh,GLint sw, Font Sfont) {    Bitfont = Sfont;    tx = sx/Bitfont.MaxW;    ty = sy/Bitfont.MaxH;    th = sh/Bitfont.MaxH;    tw = sw/Bitfont.MaxW;}void Char::display(GLint px, GLint py, GLfloat FontSize, GLfloat Roto) {    glBindTexture( GL_TEXTURE_2D, Bitfont.Tex);    glPushMatrix();    glTranslatef(px+((tw*FontSize)/2),py+((th*FontSize)/2),0);    glRotatef(Roto, 0, 0, 1);    glTranslatef(-px-((tw*FontSize)/2),-py-((th*FontSize)/2),0);    glBegin( GL_QUADS );    //Bottom-left vertex (corner)    glTexCoord2f( tx, ty );    glVertex2f( px, py);    //Bottom-right vertex (corner)    glTexCoord2f( tx, th );    glVertex2f( px, py+th*FontSize);    //Top-right vertex (corner)    glTexCoord2f( tw, th );    glVertex2f( px+tw*FontSize, py+th*FontSize);    //Top-left vertex (corner)    glTexCoord2f( tw, ty );    glVertex2f(px+tw*FontSize, py);    glEnd();    glPopMatrix();    glLoadIdentity();}SDL_Rect GetCharBox(int c) {    SDL_Rect temp;    if(c == 'A') {  temp.x = 240;  temp.y = 0;  temp.w = 16;  temp.h = 22;  return temp;    }    if(c == 'B') {  temp.x = 75;  temp.y = 28;  temp.w = 14;  temp.h = 22;  return temp;    }    if(c == 'C') {  temp.x = 88;  temp.y = 73;  temp.w = 12;  temp.h = 17;  return temp;    }    if(c == 'D') {  temp.x = 120;  temp.y = 73;  temp.w = 9;  temp.h = 17;  return temp;    }    if(c == 'E') {  temp.x = 230;  temp.y = 46;  temp.w = 13;  temp.h = 17;  return temp;    }    if(c == '[') {  temp.x = 0;  temp.y = 0;  temp.w = 13;  temp.h = 29;  return temp;    }    if(c == ']') {  temp.x = 14;  temp.y = 0;  temp.w = 14;  temp.h = 29;  return temp;    }    if(c == '(') {  temp.x = 30;  temp.y = 0;  temp.w = 10;  temp.h = 29;  return temp;    }    if(c == '$') {  temp.x = 53;  temp.y = 0;  temp.w = 12;  temp.h = 27;  return temp;    }    if(c == '/') {  temp.x = 65;  temp.y = 0;  temp.w = 15;  temp.h = 26;  return temp;    }    if(c == '{') {  temp.x = 81;  temp.y = 0;  temp.w = 11;  temp.h = 25;  return temp;    }    if(c == '|') {  temp.x = 93;  temp.y = 0;  temp.w = 4;  temp.h = 26;  return temp;    }    if(c == 'J') {  temp.x = 109;  temp.y = 0;  temp.w = 15;  temp.h = 25;  return temp;    }    if(c == 92 ) {  temp.x = 125;  temp.y = 0;  temp.w = 15;  temp.h = 25;  return temp;    }    if(c == '}') {  temp.x = 141;  temp.y = 0;  temp.w = 10;  temp.h = 25;  return temp;    }    if(c == 'H') {  temp.x = 152;  temp.y = 0;  temp.w = 10;  temp.h = 25;  return temp;    }    if(c == '%') {  temp.x = 163;  temp.y = 0;  temp.w = 15;  temp.h = 17;  return temp;    }}and while i'm not sure this terribly matters here is all my code for the actual program.  #include <Engine.h>SDL_Event event;GLfloat pi = 3.1415926535897932384626433832795;SDL_Color textColor = { 255, 255, 255 };GLint i, j, k, x;GLfloat theta;bool KeyBuffer[257];int MouseBuffer[5];vector<SpriteDispInfo> Info_Buffer;vector<Sprite>  Sprite_Buffer;Music Music_Buffer;vector<Sound> Sound_Buffer;using namespace std;void UpdateKeyBuffer() {    Uint8 *keystate = SDL_GetKeyState(NULL);    for (i=0;i<257;i++) {   if ( keystate ) {  KeyBuffer=true;   } else {  KeyBuffer=false;   }    }}void UpdateMouseBuffer() {    Uint8 MouseState = SDL_GetMouseState(&MouseBuffer[0],&MouseBuffer[1]);    if (MouseState&SDL_BUTTON(SDL_BUTTON_LEFT)) {   MouseBuffer[2] = 1;    } else {   MouseBuffer[2] = 0;    }    if (MouseState&SDL_BUTTON(SDL_BUTTON_RIGHT)) {   MouseBuffer[3] = 1;    } else {   MouseBuffer[3] = 0;    }    if (MouseState&SDL_BUTTON(SDL_BUTTON_MIDDLE)) {   MouseBuffer[4] = 1;    } else {   MouseBuffer[4] = 0;    }}class Zombie {public:    Sprite DispSprite;    Sprite Target;    float x,y,h,w,rotation;    void init(Sprite initSprite, Sprite initTarget);    void update(Sprite initTarget);};vector<Zombie> Zombie_Buffer;class Arrow {public:    Sprite DispSprite;    void init(Sprite initSprite);    void update();};void Zombie::init(Sprite initSprite,Sprite initTarget) {    Target = initTarget;    DispSprite = initSprite;}void Zombie::update(Sprite initTarget) {    Target = initTarget;    GLfloat Dist,attackDist,tx,ty,rad,degrees;    Dist = sqrt(pow((Target.x-DispSprite.x),2)+pow((Target.y-DispSprite.y),2));    attackDist = sqrt(pow((DispSprite.h/2),2)+pow((DispSprite.w/2),2));    if (Dist >= attackDist) {   if (DispSprite.x < Target.x) {  DispSprite.x += rand() % 2 + 1;   }   if (DispSprite.x > Target.x) {  DispSprite.x -= rand() % 2 + 1;   }   if (DispSprite.y < Target.y) {  DispSprite.y += rand() % 2 + 1;   }   if (DispSprite.y > Target.y) {  DispSprite.y -= rand() % 2 + 1;   }   tx = Target.x - DispSprite.x;   ty = Target.y - DispSprite.y;   if (tx == 0 && ty<0) {  degrees = 0;   }   if (tx == 0 && ty>0) {  degrees = 180;   }   rad = atan(ty/tx);   if (Target.x < DispSprite.x) {  degrees = rad*180/pi-90;   }   if (Target.x > DispSprite.x) {  degrees = rad*180/pi+90;   }   DispSprite.rotation = degrees;   DispSprite.display();   if (DispSprite.x == 1920) {  DispSprite.x = 0;   }   if (DispSprite.y == 1080) {  DispSprite.y = 0;   }    } else {   rad = atan(ty/tx);   if (Target.x < DispSprite.x) {  degrees = rad*180/pi-90;   }   if (Target.x > DispSprite.x) {  degrees = rad*180/pi+90;   }   if (tx == 0 && ty<0) {  degrees = 0;   }   if (tx == 0 && ty>0) {  degrees = 180;   }   degrees += rand() % 40 + 0;   DispSprite.rotation = degrees;   DispSprite.display();   if (DispSprite.x == 1280) {  DispSprite.x = 0;   }   if (DispSprite.x == 0) {  DispSprite.x = 1280;   }   if (DispSprite.y == 1280) {  DispSprite.y = 0;   }   if (DispSprite.y == 0) {  DispSprite.y = 1280;   }    }}void Arrow::init(Sprite initSprite) {    DispSprite = initSprite;    DispSprite.rotation = 315;}void Arrow::update() {    DispSprite.x = MouseBuffer[0];    DispSprite.y = MouseBuffer[1];    DispSprite.display();}class Player {public:    Sprite DispSprite;    Arrow Target;    void init(Sprite initSprite);    void update(Arrow initTarget);};void Player::init(Sprite initSprite) {    DispSprite = initSprite;}void Player::update(Arrow initTarget) {    Target = initTarget;    float tx,ty,rad,degrees;    tx = Target.DispSprite.x - DispSprite.x;    ty = Target.DispSprite.y - DispSprite.y;    rad = atan(ty/tx);    if (KeyBuffer[SDLK_w]) {   DispSprite.y -= rand() % 4 + 1;    }    if (KeyBuffer[SDLK_a]) {   DispSprite.x -= rand() % 4 + 1;    }    if (KeyBuffer[SDLK_s]) {   DispSprite.y += rand() % 4 + 1;    }    if (KeyBuffer[SDLK_d]) {   DispSprite.x += rand() % 4 + 1;    }    if (tx == 0 && ty<0) {   degrees = 0;    }    if (tx == 0 && ty>0) {   degrees = 180;    }    if (Target.DispSprite.x < DispSprite.x) {   degrees = rad*180/pi-90;    }    if (Target.DispSprite.x > DispSprite.x) {   degrees = rad*180/pi+90;    }    if (tx == 0 && ty<0) {   degrees = 0;    }    if (tx == 0 && ty>0) {   degrees = 180;    }    DispSprite.rotation = degrees;    DispSprite.display();    if (DispSprite.x == 1280) {   DispSprite.x = 0;    }    if (DispSprite.x == 0) {   DispSprite.x = 1280;    }    if (DispSprite.y == 1080) {   DispSprite.y = 0;    }    if (DispSprite.y == 0) {   DispSprite.y = 1080;    }}void Loop() {    Music_Buffer.Play();}int main_loop() {    bool quit = false;    GLfloat testRotation,TestSize;    Zombie tempZombie;    Player myGuy;    Arrow arrow;    Timer fps;    Font TestFont;    Char TestChar;    Sound tempSound;    Sound Beep;    TestFont.init("Font.png");    TestChar.init(0,0,26,26,TestFont);    Music_Buffer.init("labyrinth.mod");    Music_Buffer.Play();    string File = "badguy2.png";    string File2 = "test.png";    string File3 = "myGuy.png";    tempSound.init("gunshoot.wav");    Beep.init("beeptone.wav");    Sound_Buffer.push_back(tempSound);    Sound_Buffer.push_back(Beep);    Sprite tempS;    SpriteDispInfo tempI;    tempI.init(File);    Info_Buffer.push_back(tempI);    for (i=0;i<3600;i++) {   tempS.init(Info_Buffer.at(Info_Buffer.size()-1), rand() % 1920 + 1, rand() % 1080 + 1);   tempZombie.init(tempS, myGuy.DispSprite);   Zombie_Buffer.push_back(tempZombie);    }    tempI.init(File3);    Info_Buffer.push_back(tempI);    tempS.init(Info_Buffer.at(Info_Buffer.size()-1), 500, 500);    myGuy.init(tempS);    tempI.init(File2);    Info_Buffer.push_back(tempI);    tempS.init(Info_Buffer.at(Info_Buffer.size()-1), 0, 0);    arrow.init(tempS);    i = 0;    j = 0;    k = 0;    x=0;    theta = 0;    testRotation = 0;    while (quit == false) {   fps.start();   while (SDL_PollEvent (&event)) {  UpdateKeyBuffer();  UpdateMouseBuffer();  if (event.type == SDL_KEYDOWN) { if (event.key.keysym.sym == 27) {quit = true; }  }  if (event.type == SDL_QUIT) { //Quit the program quit = true;  }   }   glClear( GL_COLOR_BUFFER_BIT );   if (MouseBuffer[2]) {  Sound_Buffer.at(0).Play();   }   Mix_HookMusicFinished(Loop);   testRotation++;   if ( testRotation == 360 ) {  testRotation = 0;   }   TestChar.display(500,500,100,testRotation);   myGuy.update(arrow);   for (j=0;j<Zombie_Buffer.size();j++) {  Zombie_Buffer.at(j).update(myGuy.DispSprite);  if (checkCollsionBoundingBox(myGuy.DispSprite, Zombie_Buffer.at(j).DispSprite)) { Zombie_Buffer.at(j).DispSprite.kill();  }   }   arrow.update();   //Update the screen   SDL_GL_SwapBuffers();   //Cap the frame rate   if (fps.get_ticks() < 1000 / 60) {  SDL_Delay ( (1000 / 60) - fps.get_ticks());   }    }}int main (int argc, char *argv[]) {    srand (time (NULL));    init();    main_loop();    return 0;} thanks   
  It seems you try to delete stuff which you have not created with a new keyword. So basically don't delete them, there is no need and it doesn't make sense.For example in Sprite you try to delete the declared variable GLfloat x.Reconsider every delete &whatever. That basically is a warning sign, if whatever is a pointer, it doesn't need the "&". And if it isn't a pointer you should not be deleting it.   ;  ok i don't terribly care about things like x and y, but i wont accept leaving a texture in memory, so how do i get rid of it?   ;  You just don't understand how destructors work.  In C++ a destructor is automatically called whenever a class goes out of scope.  Destructors for all the members of a class are also automatically called.  The only time that you need to explicitly use the delete keyword is when you have used the new keyword.If you want to manually manage when your sprites are cleaned up then there are 2 things you need to do:1) Author proper destructors: i.e. only use the delete keyword on variables that were created via new2) use the new keyword to create sprite instances:  Sprite *newSprite = new Sprite();Then call delete on a pointer to the instance when you want it dead.Not enough time to read through you wall of code [smile]-me   ;  alright your right i don't understand how they work but my mind is now at ease thanks to something i took care of a couple weeks ago. i used the glDeleteTextures function, my program didn't crash this time but all my sprites that used the same texture as the one that was just removed turned into white squares. i thought about it for a second and remembered something that Amrazek helped me with. i was only using one texture to render them all so when i "deleted" it there was no texture for them. so i will just make a clean up function for the end of the program. thank you any way.   