Where to allocate one time use class? - c++

Lets consider the following code:
void main(int argc, char* argv[])
{
Foo foo;
//at this point I don't need foo any more
//a lot of stuff here
}
If I only need foo only for short amount of time,isn't it would be better to allocate it on a heap and delete before executing rest of the code?

No, it's better to write an inner scope.
int main()
{
{
Foo foo;
// use foo
}
// more code
}
But doing this should be a hint that it might be better to put foo in a completely separate function.
There's no reason to use heap allocation here though. That solution would be worse than the problem.

Related

Clearing stack memory allocated in main()?

I've been calling heap pointers now for as long as I can remember, which in turn has caused me to think about their implications while writing and what I realised was I have no knowledge on how or even if it is possible to clear a stack variable declared within main() from memory once it has been allocated.
Clearly I can just use a struct and destructor or similar, which I would but lets for say I wanted to remove an array that was on the stack declared in main() is it possible?
I wanted to remove an array that was on the stack declared in main()
is it possible?
Yes.
In main() (and most anywhere you use an automatic variable), you can trigger a dtor by closing the containing scope.
Example:
int main(int argc, char* argv[])
{
int retVal = 0;
int arr[10];
T610_t t610;
retVal = t610.exec(argc, argv);
// ...
// ... // t610 exists to end of main() scope.
// ... // arr[10] exists to end of main() scope
return retVal;
}
Instance t610 (of the user defined T610_t type) lasts the life-time of the program, even when not used after the exec() returns retVal;
In contrast:
int main(int argc, char* argv[])
{
int retVal = 0;
{
int arr[10];
T610_t t610;
retVal = t610.exec(argc, argv);
}
// ... // no t610 instance exists, and arr[] is no longer accessible
// ...
// ...
// ...
return retVal;
}
The dtor of instance t610 is called at the close-brace after exec() returns retVal. arr[10] also no longer exists.
All the lines after the close brace do not have access to T610_t, nor arr[10], and any automatic memory grabbed in the 'small scope' is 'released' for re-use. (for instance, another T610_t instance...)
Any 'clearing' of the space used by T610_t is dependent on what the dtor does and what you mean by clearing. Thus, for instance, an array data attribute of T610_t can be filled with 0's (to 'clear' it), and the dtor also releases the memory for re-use. Remember, do no delete when you did no 'new'.
No, you can't really remove a variable out of the current, local scope.
It's not something you should be concerned with - the compiler takes care of everything there.
If you are concerned about privacy, you can of course blank the variable out after use.
A semi-answer to demonstrate a trick the actual answers neglected. (Edit: Neglect changed by the time this was posted)
If you have a large block of memory that you allocated on the stack (an Automatic allocation) and you need that memory back without returning from the function, you can introduce a new scope by calling another function
int get_and_compute()
{
int array[1024*1024];
read_in_a_lot_of_inputs(array);
return compute_stuff_with__array(array);
}
int main()
{
int result = get_and_compute();
// now you have enough memory to call
job_that_takes_a_lot_of_RAM(result);
}
Or by surrounding the code in question with a set of braces
int main()
{
int result = 0;
{ //introduce a new scope
int array[1024*1024];
read_in_a_lot_of_inputs(array);
result = compute_stuff_with__array(array);
} // array goes out of scope here
// now you have enough memory to call
job_that_takes_a_lot_of_RAM(result);
}
Most of the time I prefer option 1, adding a function, but there are times where the extra function doesn't make much sense. Pick the option that is easiest to read, write, and maintain.
I wanted to remove an array that was on the stack declared in main() is it possible?
Simply let the execution go out of the scope where the automatic variable is declared:
int main() {
{
int arr[10];
}
// arr is destroyed, and further local variables can reuse its memory
}

Why can't I add an item to my vector?

I have watched all tutorials and my steps are correct but I still can't get vector to work. Below is my main function.
int main(int argc, char* argv[]) {
std::vector list<test>;
list.push_back(new test());
}
I wish to add a custom custom class which is test. Header is below
#ifndef GIVE_ME_BRAIN_TEST_H
#define GIVE_ME_BRAIN_TEST_H
class test {
public:
test();
};
The class definition is below
#include "test.h"
test::test(){}
#endif //GIVE_ME_BRAIN_TEST_H
However, compiler keeps on spitting out this message.
Googling all suggests my code is correct. What am I doing wrong?
First, std::vector list<test> nerds to be declared as std::vector<test> list instead. That's actually why the compiler complains.
Second, std::vector<test> is a vector containing actual test objects. In your case, new test() returns a pointer to a test object. Your vector doesn't accept pointers to test objects.
Try this instead:
std::vector<test> list;
list.push_back(test());
Otherwise it will keep complaining.
Notice that new is not used anymore. As mentioned in the comments, do not forget that in C++ (unlike in Java, for example) every call to new has to be matched by a call to delete in order to avoid memory leaks. There is no automatic garbage collection. If you forget this, the compiler will not complain, but your program will use more and more memory and potentially (eventually) slow down your system and/or crash.
You wrote
std::vector list<test>;
But the correct syntax is
std::vector<test> list;
Also you can't add a pointer to the vector of objects. You need to dereference it:
auto tmp = new test();
list.push_back(*tmp);
First: Please add #include <vector>
Second: The line std::vector list<test>; need to be replaced with std::vector<test> list
Third: list.push_back take reference as parameter not pointer, so changed as follows:
test *tmp = new test();
list.push_back(*tmp);
The final solution is:
#include <iostream>
#include <vector>
using namespace std;
class test {
public:
test() {
}
};
int main(int argc, char* argv[]) {
std::vector<test> list;
test *tmp = new test();
list.push_back(*tmp);
}

Using member functions to deal with objects in the heap (c++)

I'm a beginner with C++, and this is a pretty basic syntax question, but i can't seem to find an answer elsewhere. Any input would be welcome. Here is a simplified version of the problem.
Say I have a class 'pair'
class pair
{
int a;
int b;
public:
pair(int x,int y)
{
a=x;
b=y;
}
int lookup()
{
return this->a+b;
}
};
Then i instanciate and copy that instance to a spot on the heap.
int func()
{
...
pair test(1,2);
pair *ptr=new pair;
*ptr=test;
}
Now here is the key. I don't destroy this memory allocation after the function ends. I want to use it later in this other function. The problem is, i would prefer to keep it in the heap and NOT have to copy it over to the stack(in the actual program it is very large). I would therefore like to do something like this:
int otherfunc()
{
...
int sum=*ptr.lookup;
}
but I get a compiler error. I end up having to do something like:
int otherfunc()
{
...
point temp=*ptr;
int sum=temp.lookup;
}
While this works, it is redundant, and when dealing with really large things it can even potentially cause an overflow. Anyone know the syntax for calling the method using the pointer while keeping it on the heap? Thanks.
I believe this is what you are trying to do:
int sum = ptr->lookup();
And as an aside, this:
return this->a+b;
Would probably be better as just this:
return a+b;
The expression *ptr.lookup will be interpreted as *(ptr.lookup), which is why you get the syntax error because ptr.lookup does not make sense. You'll need to tell the compiler dereference ptr first by using the parenthesis: (*ptr).lookup.
Because pointers are common in C (and C++), the (*a).b can be written in a simpler form: a->b.
Also, lookup is a function even if it does not take any parameters. You need to call it with ():
int sum=ptr->lookup();

avoiding global variables while using GLUT

GLUT is a great API and it's very easy to use but I am having some difficulty with how it handles scope. When defining callbacks there is no option to pass parameters so it seems to me as though the programmer is forced to rely on global variables, which I find difficult to accept. Right now I have all the GLUT code in it's own module, running on it's own thread, and define a static pointer which I assign at the entry point to the module, like so:
Main module
int main( int argc, char** argv ) {
int foo;
boost::thread graphicsThread(glutMain, argc, argv, &foo);
//...
graphicsThread.join();
return 0;
}
GLUT module
static int* FOO_REF;
int glutMain( int argc, char** argv, int* foo ) {
FOO_REF = foo;
glutInit(&argc, argv);
//etc...
Is there a better solution than this?
If you're using freeglut or a derivative and willing to confine yourself to freeglut derivatives only it has a non-standard extension to solve exactly the problem. You can associate a void* with every window. If you make that a struct that contains all the per-window data you want you can avoid the globals entirely.
Synopsis:
#include <GL/glut.h>
#include <GL/freeglut_ext.h>
void * glutGetWindowData();
glutSetWindowData(void *data);
What I did was declare a global.h for all my globals. And initialize them in main. For my "basic/general" variables (ie camera, position, iterationNumber,...) they were all declared seperately. In main:
include "global.h"
Vector position_g = ...
Vector angles_g = ...
int time_g = 0;
int main () {
...
}
But for the variables that were "section specific" ie only in one game mode/level, I made a union and an enum.
enum mainGame{skipLevel, ...};
enum mainMenu {viewingSettings, ...};
typedef union generic_union {
int i;
char c;
bool b;
char s[100]; // or char * s;
float f;
} generic;
And declared a globalData variable.
extern generic * globalData; // in global.h
generic * globalData = NULL; // in main
Which can now be used:
int main () {
...
globalData = malloc (sizeof (generic)*numGlobals);
globalData[skipLevel].b = false;
...
}
Now when in your key press handling function, you can assign a key to toggle globalData[skipLevel]. And in any other file all you have to do is include global.h.
include "global.h"
void onKeyPress (... ) {
If (inMainGame) {
If (key == SPACE) {
globalData [skipLevel] = true;
}
}
And finally the use:
include "global.h"
void levelManager () {
...
if (globalData[skipLevel]) level++;
...
}
Pros
Only have to lug around 1 variable and one include.
You can free variables you no longer want or are using in that instance. (very useful for reducing "pollution"). If one game mode only needs 1 variable, thats all you have to store, if it needs 48, just as easy!
Can easily handle any variable type, by adding it to the union.
Totally Portable
Cons
Have to remember variable type to dereference the generic union (not that hard)
And watchout for enums being used (you can use a style for enums like mainMenu_e to solve this)
Adds complexity, but as the variable number grow, a system like this because well worth it.
Personally I find this very neat despite the few extra moving parts.
If this is unclear let me know, and Ill try to fix it :)

constructors and destructors - c++

I need to write a program that prints 100 stars on the screen (at random places), and then the stars disappear slowly - one after another. I'm not allowed to use loops nor recursions.
I've tried to play with the constructors and the destructors but I can't get the stars to disappear one after another (and not all together).
Any ideas?
Thanks,
Li
Sorry - forgot to mention i'm using c++
My current access violating useless code:
class star {
int x;
int y;
public:
star(){
x = rand()%80;
y = rand()%80;
PaintcharOnRandomLocation('*',x,y);
};
~star(){
PaintcharOnRandomLocation(' ',x,y);
};
};
class printAll{
star* arr;
public:
printAll(){
arr = new star[100];
};
~printAll(){
delete[] arr;
};
};
void doNothing(printAll L){
};
void main()
{
srand ( time(NULL) );
doNothing(printAll());
getch();
};
Seems the only way possible without loops/recursion is something like this:
class Star
{
Star()
{
//constructor shows star in a a random place
}
~Star()
{
//destructor removes star and sleeps for a random amount of time
}
};
int main()
{
Star S[100];
}
This is really just a dumb trick because the compiler has to run the constructor for each star to initialise the array and then the destructor for EACH star as it goes out of scope.
It is also a bad trick as all the workings that go in the main function are opaque and invisible. It would obviously be better to use a loop in this context and putting the delay inside a destructor like this is really confusing and unmaintainable.
This is not a runtime recursion:
template<int N>
struct Star
{
Star() { DrawAtRandomPlace(); }
~Star() { RemoveSlowly(); }
Star<N-1> star;
};
template<> struct Star<0> {};
int main()
{
Star<100> stars;
}
The code above will generate 100 different instantiations of the Star template. RAII will guarantee the order of drawing and removing.
Based on your final comment, can you have the destructor of your star class do a delay? See for example the sleep or usleep functions.
Since Destructors/Constructors are only an Idea, they're probably not the right title for your question.
I don't know what system/environment you are in, but how about this:
Create a buffer that contains a string with your stars, simply manually by typing them in the code.
Next, write a function that displays the buffer to whatever output window you use.
Then, you would need a function that has a static(!) pointer to the back of the buffer, and that does the following:
Call the buffer printing function
Write a null byte under the current pointer position
Decrement the static pointer
Wait for a period of time
Raise a custom signal with raise()
In the main() function, you set the the Signal Handler for your custom signal to the function described above, and then you raise the custom signal.