C++ method variable declaration - c++

Currently I'm looking into this C++ source code. I'm not a C++ dev.
void SomeClass::SomeMethod() const
{
vector<Thing> things(count);
...
//Elements are added or replaced in things but no deallocation of things here
}
SomeMethod is called a lot of times. Could anyone confirm that there is no leak and things is allocated only once, reference would be appreciated.

The vector is created everytime you enter the function and destroyed (destroying all objects and freeing all the memory) when it leaves scope (when the function ends). There's no leak, but there's a lot of allocations and deallocations if you call that function frequently.
You have 2 solutions to avoid that:
(preferred) Make this vector a class field (with attribute mutable in order to allow it to be changed by a const method),
Make this vector a static variable.

"things" is a local auto variable.
Another post has a answer for this: Where are the local, global, static, auto, register, extern, const, volatile variables are stored?

Provided Thing is correctly implemented insofar as its destructor and other member functions (especially copy constructor because that's used in vector housekeeping) correctly handle all memory for its data members, what this will do is create a new vector<Thing> on each call to the function.
The resulting local variable things gets correctly freed, including destruction of every Thing member, when the variable goes out of scope (i.e. on function exit).
It's impossible to be more definitive without seeing all the code in the method and in Thing, but this usage is on the face of it correct.

That lays localy in that function. When it goes out of scope, it will delokate the memory by itself; all of the STL containers do.

Related

Memory alocated for Creating object inside a function?

As objects are created from same class. Each object contains the variable defined in the class except those which are defined in the methods of that class. Variable in functions of the same object are shared memory right? If we have a function where we create an object of the same class, where will be the reference reside? Isnt that reference be shared too?
Methods are no different from any other function with regard to memory use: local variables are created when execution reaches their declaration, and (unless static) they are destroyed, and their memory reclaimed, when execution leaves the block it. (This happens, at latest, when the function returns.) There is no connection to the this object or any of its members. Nor does the variable having the same type as the method’s class make any difference.
In some sense, that does make the memory “shared”: it will be rapidly reclaimed and (typically) reused. But that’s nothing special, and don’t think that it means more than it does: if a method is recursive, or invoked concurrently by more than one thread, each copy has its own locals—again, just like any other function.
Finally, any function or method can allocate memory dynamically; the lifetime and sharing of the allocated object may be unrelated to that of the variable used to refer to it.

Class destructors and pointer deallocation

I am writing a class (virtual_flight_runtime_environment), and it is mostly non-static, with the exception of one static function for the purposes of a Win32 thread using it as its function. The class declares struct simaircraftdata* aircraftdata (a data struct), and calls 'aircraftdata = new aircraftdata;' in the constuctor (public: virtual_flight_runtime_environment()).
My question is about destructors and memory deallocation. I have written the destructor as such:
~virtual_flight_runtime_environment(void) {
/*..Other code, i.e. closing win32 handles, etc.*/
delete aircraftdata;
}
Now, the class is declared in another function (the DoWork function of a .Net background worker) like so:
virtual_flight_runtime_environment* this_environment = new virtual_flight_runtime_environment;
And just before the end of the function, I call 'delete this_environment;'. Immediately after, 'this_environment' would have gone out of scope, and the desturctor should have been called.
Is this correct? I do notice continued increases in memory usage over time, and I'm wondering if I've done something wrong. Does calling delete on a pointer just make it a null pointer, or does it deallocate the data at the end of it?
Any advice would be appreciated,
Collin Biedenkapp
There is no direct connection between a delete in your program and whether it will directly be visible in say the task manager because the OS tries to optimize memory utilization. When you look in the task manager you will typically see the working set size of your application, this is a measure of how much memory your app has requested but not necessarily how much it is currently using.
And to your question, yes deleting the memory as you did it is the WTG although as others have pointed out using smart pointers is generally much better to handle memory to avoid later headaches.
You're almost correct.
delete this_environment calls the destructor of virtual_flight_runtime_environment. The destructor executes delete aircraftdata.
Right after that, the memory occupied by the instance of virtual_flight_runtime_environment is released.
Please be aware that delete statement doesn't set the pointer to NULL.
So I see no problem in your code given the information in the question.
This looks correct.
Calling delete on your this_environment will cause the destructor of that class to be called before it's memory is deallocated. The destructor deletes the aircraft data. Looks correct.
You might consider instead of having a member variable containing a raw pointer to aircraftdata instead using an auto_ptr or in c++11 unique_ptr which will ensure that it gets deleted automatically when it's containing class is constructed. Look it up, this isn't the place to teach it and it's just a suggestion, not a necessity.
Edit: And I also agree with Pete Becker's comment on the question, which is to question if this needs a pointer at all.
You should indeed explicitely call "delete this_environment". Otherwise, it's only the pointer itself (which exists on the stack) which would be destroyed. The data pointed, on the heap, would still exist.
The other solution is to simply get rid of the pointer and declare your variable as such :
virtual_flight_runtime_environment this_environment;
That way, your object will directly exist on the stack, and its lifetime will depend on the scope in which it is declared - and the destructor will be automatically called at this point, calling in turn the delete for your internal data.

Managing Scope and Object Lifetime Within STL Vectors

Coming from a C# world, I'm struggling to make sure I don't introduce memory leaks and errors in a C++ project I've been assigned to. I'm writing code that uses structs to parse information from a buffer of data. Because the number of data structures that appear in the buffer can vary at runtime, an stl vector is used to store the processed data. I came across the following block of code in the existing software, and am struggling to understand why it works:
MyVectorOfObjects.clear();
for (unsigned __int8 i = 0; i < NumberOfObjects; i++)
{
MyParserObject parserObject; // Declaring without 'new'?
parserObject.Decode(buffer, offset, size); // A method on the struct.
MyVectorOfObjects.push_back(parserObject); // Does this keep parserObject in scope?
}
My questions are specifically:
According to this question, wouldn't parserObject go out of scope each iteration since the new keyword isn't used? Evidently this code has been working.
In this case, does placing the object in a vector keep the parserObject in scope?
According to this question, the parserObject is copied. If this is the case, what are the performance implications (e.g. memory consumption, memory allocation, etc.) of this? Also, do the copied parserObjects then assume the same scope as the vector?
Thanks for any help.
Yes, the instance of parserObject that is declared within the for loop goes out of scope each time the loop iterates.
No, placing the parserObject into the vector doesn't keep that object in scope. The push_back() method will make a copy of that object that is now owned by the vector. You need to make sure your objects can be properly copied (copy-constructor and assignment operator may be necessary). Copies contained in the vector in this example are owned by the vector, and will have object lifetimes that are similar to the vector itself.
The paserObject is copied, and this may have implications on memory usage and performance. If the parserObject is not trivial to copy then this can be an expensive operation. This is wholly dependent upon your implementation of the parserObject.
MyVectorOfObjects.push_back(parserObject); // Does this keep parserObject in scope?
push_back makes a copy of the object and stores it.
So make sure that you've defined copy-constructor (and copy-assignment) properly for the class MyParserObject if it has pointer member(s). Or else default code generated by the compiler would be enough, provided each member of MyParserObject follows the same pattern (i.e they've defined the copy-constructor (and copy-assignment) properly if they've pointer members, or else default-code generated by the compiler would be enough, provided .... and so on.)

How to free static member variable in C++?

Can anybody explain how to free memory of a static member Variable? In my understanding it can only be freed if all the instances of the class are destroyed. I am a little bit helpless at this point...
Some Code to explain it:
class ball
{
private:
static SDL_Surface *ball_image;
};
//FIXME: how to free static Variable?
SDL_Surface* ball::ball_image = SDL_LoadBMP("ball.bmp");
The pointer itself will be around until the program shuts down. However, what it points to is fair game. You can free that at any time.
If what you're worried about is memory leaks, then you have a few options that I see:
Just let it leak. All the memory from the program will be released when it shuts down. However, if you need more than just the memory being freed (like you want a destructor to run), then that's not such a good idea.
Have a static member variable which keeps track of how many instances of the class have been created. Free the memory when it reaches zero and reallocate it if it goes above 0 again.
Have a function of some kind which runs when the program is shutting down and have it worry about freeing the memory.
If you can, make it so that it's not a pointer anymore. If it's not a pointer, you don't have to worry about it.
Use a smart pointer or auto_ptr. That way, when the pointer itself is destroyed, the memory will be taken care of.
Personally, I'd advise 4 if you can and 5 if you can't, but you have several options.
From the sound of it, you don't really want a pointer at all. In fact, since this is coming from a factory function in a C library, it isn't really a "first-class" C++ pointer. For example, you can't safely delete it.
The real problem (if there is one) is to call SDL_FreeSurface on it before the program exits.
This requires a simple wrapper class.
struct smart_sdl_surface {
SDL_Surface *handle;
explicit smart_sdl_surface( char const *name )
: handle( SDL_LoadBMP( name ) ) {}
~smart_sdl_surface()
{ SDL_FreeSurface( handle ); }
};
class ball
{
private:
static smart_sdl_surface ball_image_wrapper;
static SDL_Surface *& ball_image; // reference to the ptr inside wrapper
};
smart_sdl_surface ball::ball_image_wrapper( "ball.bmp" );
SDL_Surface *&ball::ball_image = ball::ball_image_wrapper.handle;
When the program initializes, the constructor is called and the file is read. When the program exits, the destructor is called and the object is destroyed.
The static member variable in this case is a pointer. You can't free it, but you can free what it points to:
SDL_FreeSurface(ball_image);
You might then want to set ball_image to 0, to record the fact that you no longer have an image.
it can only be freed if all the instances of the class are destroyed
If by "the class" you mean ball, then no. Static members of ball continue to exist regardless of how many instances of ball there are. The only way a static member might be destroyed before program exit is if you do some (implementation-dependent) thing like unloading the dll which contains the class. But in this case the static member is just a pointer, so (1) destroying it will just destroy the pointer, not the pointee, and (2) there is no need to destroy a pointer anyway, it doesn't occupy significant resources.
If you must have the static member pointing to heap-allocated memory, I would make a member a smart pointer.
A static member exists completely independently of all instances of the class it is a member of. You can delete the pointer at any point in the program. Whether this makes sense semantically, is another issue, of course.
I agree with Jonathan M Davis' answer, but another option you could consider is pulling your images and other resources out of your "domain objects" and into a ResourceManager class, or something along those lines.
The ResourceManager could either be static, or instance-based, and would provide the logic to load and delete resources, needed by the rest of our application.
Classes needing resources could just hold a reference or a pointer to the global resource manager, and request resources from the manager, rather than managing them themselves.
Static member variables don't need to be deleted. If you have one within a class, is because you want to use it at any time during the entire life of the programme. Once the programme finishes, the Operating System claims back the total memory assigned to it, including any undeleted memory space.
Of course, if you insist in deleting it, you can create a special static member method for doing it and invoke the method at a desired point in the programme. But I woudn't recommend it to anyone, because it violates the semantic integrity of the static member variables, increasing so the complexity and the likelihood for causing troubles as the programme grows.
Working with a static variable where the memory is dynamically allocated, it is better to go with smart_pointer or a method where memory is cleared manually.
Clearing the memory of static varibles in the destructor will not work for the below case:
As static members exist as members of the class rather than as an instance in each object of the class. So if someone access a static variable using :: and dynamically allocate memory, the destructor will not come in picture and the memory will not get deleted, as there is no object created.

C pointer array scope and function calls

I have this situation:
{
float foo[10];
for (int i = 0; i < 10; i++) {
foo[i] = 1.0f;
}
object.function1(foo); // stores the float pointer to a const void* member of object
}
object.function2(); // uses the stored void pointer
Are the contents of the float pointer unknown in the second function call? It seems that I get weird results when I run my program. But if I declare the float foo[10] to be const and initialize it in the declaration, I get correct results. Why is this happening?
For the first question, yes using foo once it goes out of scope is incorrect. I'm not sure if it's defined behavior in the spec or not but it's definitely incorrect to do so. Best case scenario is that your program will immediately crash.
As for the second question, why does making it const work? This is an artifact of implementation. Likely what's happenning is the data is being written out to the data section of the DLL and hence is valid for the life of the program. The original sample instead puts the data on the stack where it has a much shorter lifetime. The code is still wrong, it just happens to work.
Yes, foo[] is out of scope when you call function2. It is an automatic variable, stored on the stack. When the code exits the block it was defined in, it is deallocated. You may have stored a reference (pointer) to it elsewhere, but that is meaningless.
In both cases you are getting undefined behaviour. Anything might happen.
You are storing a pointer to the locally declared array, but once the scope containing the array definition is exited the array - and all its members are destroyed.
The pointer that you have stored now no longer points to a float or even a valid memory address that could be used for a float. It might be an address that is reused for something else or it might continue to contain the original data unchanged. Either way, it is still not valid to attempt to dereference the pointer, either for reading or writing a float value.
For any declaration like this:
{
type_1 variable_name_1;
type_2 variable_name_2;
type_3 variable_name_3;
}
declaration, the variables are allocated on the stack.
You can print out the address of each variable:
printf("%p\n", variable_name )
and you'll see that addresses increase by small amount roughly (but not always exactly equal to), the amount of space each variable needs to store its data.
The memory used by stack variables is recycled when the '}' is reached and the variables go out of scope. This is done nice an efficiently just by subtracting some number from a special pointer called the 'stack pointer', which says where the data for new stack variables will have their data allocated. By incrementing and decrementing the stack pointer, programs have an extremely fast way of working out were the memory for variables will live. Its such and important concept that every major processor maintains a special piece of memory just for the stack pointer.
The memory for your array is also pushed and popped from the program's data stack and your array pointer is a pointer into the program's stack memory. While the language specification says accessing the data owned by out-of-scope variables has undefined consequences, the result is typically easy to predict. Usually, your array pointer will continue to hold its original data until new stack variables are allocated and assigned data (i.e. the memory is reused for other purposes).
So don't do it. Copy the array.
I'm less clear about what the standard says about constant arrays (probably the same thing -- the memory is invalid when the original declaration goes out of scope). However, your different behavior is explainable if your compiler allocated a chunk of memory for constants that is initialized when your program starts, and later, foo is made to point to that data when it comes into scope. At least, if I were writing a compiler, that's probably what I'd do as its both very fast and leads to using the smallest amount of memory. This theory is easily testable in the following way:
void f()
{
const float foo[2] = {99, 101};
fprintf( "-- %f\n", foo[0] );
const_cast<foo*>(foo)[0] = 666;
}
Call foo() twice. If the printed value changed between calls (or an invalid memory access exception is thrown), its a fair bet that the data for foo is allocated in special area for constants that the above code wrote over.
Allocating the memory in a special area doesn't work for non-const data because recursive functions may cause many separate copies of a variable to exist on the stack at the same time, each of which may hold different data.
It's undefined behavior in both cases. You should consider the stack based variable deallocated when control leaves the block.
What's happening is currently you're probably just setting a pointer (can't see the code, so I can't be sure). This pointer will point to the object foo, which is in scope at that point. But when it goes out of scope, all hell can break loose, and the C standard can make no guarantees about what happens to that data once it goes out of scope. It can be overwritten by anything. It works for a const array because you're lucky. Don't do that.
If you want the code to work correctly as it is, function1() is going to need to copy the data into the object member. Which means you'll also have to know the length of the array, which means you'll have to pass it in or have some nice termination method.
The memory associated with foo goes out of scope and is reclaimed.
Outside the {}, the pointer is invalid.
It is a good idea to make objects manage their own memory rather than refer to an external pointer. In this specific case your object could allocate its own foo internally and copy the data into it. However it really depends on what you are trying to achieve.
For simple problems like this it is better to give a simple answer, not 3 paragraphs about stacks and memory addresses.
There are 2 pairs of braces {}, one is inside the other. The array was declared after the first left brace { so it stops existing before the last brace }
The end
When answering a question you must answer it at the level of the person asking regardless of how well you yourself comprehend the issue or you may confuse the student.
-experienced ESL teacher