Pointers

    This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

    • I am using VLD to detect any memory leaks. The following code is reporting a memory leak.

      Source Code

      1. bool Audio::Load(std::string filename, std::string name)
      2. {
      3. if (filename.length() == 0 || name.length() == 0) return false;
      4. Sample *sample = new Sample();
      5. sample->setName(name);
      6. try { FMOD_RESULT res;
      7. res = FMOD_System_CreateSound( system, //FMOD system filename.c_str(), //filename
      8. FMOD_DEFAULT, //default audio
      9. NULL, //n/a
      10. &sample->sample);
      11. //pointer to sample if (res != FMOD_OK)
      12. { return false; } } catch (...) { return false; }
      13. samples.push_back(sample);
      14. return true;
      15. }
      Display All


      My question is once sample is added to samples, is the local pointer to sample still needed? If I delete sample, will this cause the samples vector to have an invalid pointer?

      The definition of samples is as below:
      typedef std::vector<Sample*> Samples;
      typedef std::vector<Sample*>::iterator Iterator;
      Samples samples;
    • First, you should never ever ever use exceptions in C++. Never. It's incredibly slow and way too invasive for a real-time application.

      If I'm reading this correctly, it looks like Sample is your own class, which contains an element called sample, which is an FMOD_SOUND pointer, correct? You can't delete sample in this example because you're pushing it to the vector. You are correct, the vector will have an invalid pointer.

      Your bracing is a bit confusing with the try/catch and additional error checking. It looks like if something goes wrong, you'll leak right away because you're returning false. You should delete the sample pointer in that case.

      Other than that, my guess is that your Audio destructor isn't going through the samples vector and destroying each sound, which you'll need to in order to free that memory.

      -Rez
    • Rez,
      Thanks for the feedback. Yes, Sample is a separate class that represents a FMOD_SOUND pointer. Yes, sample is a member of Sample:

      FMOD_SOUND *sample;

      Thanks for the note on the exception handling, I will be removing it.

      As for the delete of the samples vector, it is in the destructor:

      Source Code

      1. Audio::~Audio()
      2. {
      3. //release all samples for (Iterator i = samples.begin(); i != samples.end(); ++i)
      4. {
      5. (*i) = NULL;
      6. }
      7. FMOD_System_Release(system);
      8. }


      I will post again once I have removed the try...catch block.
    • (*i) = NULL doesn't release anything, you have to call delete:

      Source Code

      1. delete (*i);


      -Rez
    • Originally posted by MrClark
      Thank you. That fixed the leak immediately. Can you please explain why the setting of NULL in this case doesn't work and delete must be used instead?


      The delete function will actually free the memory so it can be used for something else. The = operator is not linked to memory management. This will only reset the pointer to a null value. The memory manager will still think you need the allocated buffer until you release it properly with the delete function.
      MCSE/MCDBA/Programmer C,C++,PERL,PHP
    • Originally posted by MrClark
      Great, thank you. Is this the case always? Delete frees the memory and null means null pointer?


      In reality everytime you use the new operator you should also call the delete somewhere else. They have a 1 to 1 relation ship. If you call new 3 times, you should also call delete 3 times.

      Assigning NULL to a pointer only change it's value, nothing is freed.

      I personally set the pointer to NULL after deleting it be cause this is not done automatically. When you free memory with the delete operator your pointer still hold an address which can lead to unexpected behavior.

      example:

      *p = new char[100];
      sprintf(p,"hello world\0");
      delete []p;
      p=null; //just to be safe

      so that if some part of my code needs to access 'p' I can safely check if it's still valid or not
      example:

      *p = new char[100];
      sprintf(p,"hello world\0");
      delete []p;
      p=null;

      if (p) //P still allocated
      {
      /do things
      }
      else //P was freed and set to NULL
      {
      //do things
      }


      it's a simple example
      MCSE/MCDBA/Programmer C,C++,PERL,PHP

      The post was edited 1 time, last by Slayerizer ().

    • The above code was actually attempting to set the value at the pointer address to 0 (NULL macro translates to 0). That shouldn't have been able to compile unless it was a pointer to something that can be assigned an integer value. This is also a good reason to use C++11's nullptr because it will catch if you're accidentally using NULL as an integer instead of the conceptual "null".

      James
    • First post; here it goes.

      Just purchased the 4th edition and going through it at the moment. I have question with regards to NULL in this case. With C++11's features being included in Visual Studio 2010 and above, has there been any transition to nullptr as opposed to NULL in the industry?
    • Originally posted by KITT
      First post; here it goes.

      Just purchased the 4th edition and going through it at the moment. I have question with regards to NULL in this case. With C++11's features being included in Visual Studio 2010 and above, has there been any transition to nullptr as opposed to NULL in the industry?

      Not really, no. The only feature of C++ 11 we officially use is the auto keyword. If we were to start another project, we might do it then.

      I'm not sure what the rationale is for not switching over. My guess is that the tech directors don't want to incur the risk of switching over.

      I wonder if future versions of visual studio will rewrite the NULL macro to be nullptr instead of 0.

      -Rez
    • I was under the impression that the NULL macro was not something to do with visual studio at all, I have had many times when I have not used 3rd party libraries where I have had to define NULL myself, however as almost any 3rd party lib out there defines it, you are bound to have it included in your source somehow.

      I have started using nullptr as it is a built in keyword and just tends to look nicer, no troubles yet!
      PC - Custom Built
      CPU: 3rd Gen. Intel i7 3770 3.4Ghz
      GPU: ATI Radeon HD 7959 3GB
      RAM: 16GB

      Laptop - Alienware M17x
      CPU: 3rd Gen. Intel i7 - Ivy Bridge
      GPU: NVIDIA GeForce GTX 660M - 2GB GDDR5
      RAM: 8GB Dual Channel DDR3 @ 1600mhz
    • It's not a C++ keyword, it's defined in a number of headers. You are correct that if you have a file that doesn't include anything at all and try to use NULL, it'll be a compile error. NULL is actually a macro that most compilers define as follows:

      Source Code

      1. #ifndef NULL
      2. #ifdef __cplusplus
      3. #define NULL 0
      4. #else
      5. #define NULL ((void *)0)
      6. #endif
      7. #endif


      That code was taken from windef.h. My guess is that future versions of this macro will define it to be nullptr rather than 0.

      -Rez
    • Originally posted by rezination
      Originally posted by KITT


      I wonder if future versions of visual studio will rewrite the NULL macro to be nullptr instead of 0.

      -Rez


      I doubt it.. doing so would change the behavior of programs (at least some of them).

      if you do:

      Source Code

      1. class world
      2. {
      3. void hello(int myvar);
      4. void hello(void *myvar);
      5. }


      If you call hello(NULL) if will trigger the first one, with std::nullptr, it will now trigger the second one. Changing NULL would have unwanted impacts!
      I will personally use the new null definition in my future projects.
      MCSE/MCDBA/Programmer C,C++,PERL,PHP
    • It's not a C++ keyword, it's defined in a number of headers. You are correct that if you have a file that doesn't include anything at all and try to use NULL, it'll be a compile error.


      Sorry are you saying nullptr isn't built in or NULL?

      code: class world { void hello(int myvar); void hello(void *myvar); }


      I have found that if you do something like this with plain old NULL, it will give you an ambiguous error as it isn't sure whether you want to call the int or void* version.
      PC - Custom Built
      CPU: 3rd Gen. Intel i7 3770 3.4Ghz
      GPU: ATI Radeon HD 7959 3GB
      RAM: 16GB

      Laptop - Alienware M17x
      CPU: 3rd Gen. Intel i7 - Ivy Bridge
      GPU: NVIDIA GeForce GTX 660M - 2GB GDDR5
      RAM: 8GB Dual Channel DDR3 @ 1600mhz

      The post was edited 2 times, last by mholley519 ().

    • Ok, thats what I thought as even with no includes you can still use nullptr.
      PC - Custom Built
      CPU: 3rd Gen. Intel i7 3770 3.4Ghz
      GPU: ATI Radeon HD 7959 3GB
      RAM: 16GB

      Laptop - Alienware M17x
      CPU: 3rd Gen. Intel i7 - Ivy Bridge
      GPU: NVIDIA GeForce GTX 660M - 2GB GDDR5
      RAM: 8GB Dual Channel DDR3 @ 1600mhz
    • question in this code

      I have a question about my code.
      I don't know if my code works how i think.

      Class Mapa

      C Source Code

      1. #ifndef MAPA_H
      2. #define MAPA_H
      3. #include <list>
      4. #include <vector>
      5. #include <algorithm>
      6. #include "Csprite.h"
      7. #include <fstream>
      8. #include "Boton.h"
      9. using namespace std;
      10. class Mapa
      11. {
      12. public:
      13. Mapa();
      14. ~Mapa();
      15. int cargarMapa(char *path); //carga un mapa ya creado
      16. int guardarMapa(char *path); //guarda el mapa creado
      17. int cargarTile(char *path); //cargamos un nuevo tile
      18. int guardarTiles(char *path); // guardamos en un archivo todas las rutas de los tiles
      19. void dibujarM(SDL_Surface *screen); //dibujamos la pantalla del programa
      20. int controlEventos(SDL_Event &event); //controlamos los eventos
      21. int getNumFrames(); //obtenemos el numero de frames
      22. int getNumFilas(); //obtenemos el numero de filas
      23. int getNumCol(); //obtenemos el numero de columnas
      24. private:
      25. void cargarPaths(); //cargamos todos los archivos
      26. int leerPaths(); //leemos y guardamos las rutas
      27. void rellenarMap(vector<vector<int> > &map, int fil, int col);
      28. list<char*> paths; //Lista de rutas
      29. vector<vector<int> > map; //array multidimensional para el mapa
      30. list<CFrame*> frames; //lista de frames(tiles) que tenemos
      31. list<CSprite*> sprites; //lista de sprites que guardan los tiles
      32. int numFrames, numFilas, numCol; //numFrames: numero de frames(tiles), numFilas y numCol nos indica las filas y columnas del
      33. //array
      34. vector<Boton*> botones; //7 botones en total
      35. };
      36. #endif
      Display All


      Source Code

      1. void Mapa::cargarPaths()
      2. {
      3. char *currentChar;
      4. CFrame *currentFrame;
      5. CSprite *currentSprite;
      6. for (list<char*>::const_iterator iterator = paths.begin(), end = paths.end(); iterator != end; ++iterator)
      7. {
      8. CFrame frame;
      9. CSprite sprite;
      10. currentChar = *iterator;
      11. frame.load(currentChar);
      12. currentFrame = &frame;
      13. frames.push_back(currentFrame);
      14. sprite.addframe(*currentFrame);
      15. currentSprite = &sprite;
      16. sprites.push_back(currentSprite);
      17. numFrames++;
      18. }
      19. }
      Display All

      I only want fill the vector with frames that i'm loading.
      Is this code good? and, is there another better way to make this?

      thanks ;)
      Be a pointer my friend

      The post was edited 1 time, last by budark ().

    • I think that this is already resolved :P

      Source Code

      1. void Mapa::cargarPaths()
      2. {
      3. char *currentChar;
      4. list<CFrame*>::const_iterator iteratorF = frames.begin();
      5. list<CSprite*>::const_iterator iteratorS = sprites.begin();
      6. for (list<char*>::const_iterator iterator = paths.begin(), end = paths.end(); iterator != end; ++iterator)
      7. {
      8. currentChar = *iterator;
      9. (*iteratorF)->load(currentChar);
      10. (*iteratorS)->addframe(**iteratorF);
      11. iteratorF++;
      12. iteratorS++;
      13. }
      14. }
      Display All
      Be a pointer my friend