Is there a one line approach to declaring and initializing pointer variables? - c++

When I need to create a pointer variable, I currently use the following approach which works:
int getIntPointer()
{
int * intPointer = new int;
*intPointer = 0;
return *intPointer;
}
likewise, when returning such a pointer from another function I would use something like this in main() to use it:
int main()
{
int * intPointer = new int;
*intPointer = getIntPointer();
delete intPointer;
}
This all works, but for readability and efficiency I'd like to know is if there are one line equivalents. (and I don't mean to just put them on the same line. I mean a short hand approach.)
Also: In this above example, I used the same pointer variable in both functions, and it works. Are they the same pointer in memory? Adding something like:
delete intPointer;
Immediately after the return statement doesn't crash the program, but does it even get there? Or is it safe to just delete it's passed iteration in main when no longer needed?

You could do:
int *intPointer = new int(0);
(or new int(100); if you want intPointer to point at the value 100).
And of course, you could shorten that to :
return new int(0);
assuming you don't need to do anything else with the pointer.
Note that:
int * intPointer = new int;
*intPointer = getIntPointer();
is incorrect. Either you mean:
int * intPointer = new int;
intPointer = getIntPointer();
in which case it's a memory leak, because you are overwriting intPointer from new with the one created by the call.
Or you mean to write:
int * intPointer = new int;
*intPointer = *getIntPointer();
in which case there is a memory leak because getIntPointer called new and you "lost" that pointer by not saving the return value.
For EVERY new you call, you should have exactly one corresponding delete, or it is a memory leak. Since both of my examples above does NOT provide that, because both cases will lose one of the pointers returned from new, this is incorrect.
In general, it is best to NOT use "raw pointers", and instead use either std::unique_ptr (if you only ever expect the pointer to "live" in one place at a time) or std::shared_ptr (if you expect multiple objects to have a copy of the pointer).
Edit: My answer above assumes that getIntPointer actually does what the name describes, rather than what the code in the question does, which is rather poor design: allocate memory and then return the pointed-to value.

I could be wrong, but I think you're reaching for std::shared_ptr and its helper function std::make_shared.
std::shared_ptr< int > intPointer = std::make_shared< int >( 42 );
Rather than repeat all the use cases of smart pointers here, I'll simply link to an answer that goes into more detail on the topic.
inb4 rants about why smart pointers are good or bad.

Related

Usage of asterisk(*) before new(dynamic allocation) in c++

board *gameBoard = new board(givenX,givenY,givenMineCount);
I know that the above statement declares an object pointer that points to board.
But I'm wondering what the statement below means.
board gameBoard = *new board(givenX,givenY,givenMineCount);
In both statements the "new" keyword returns a pointer to the object you are allocating. The reason the second statement works is because if you put a * before a pointer you dereference that pointer which, in simple terms, gives you the object the pointer is pointing to. But as Mooing Duck said if you don't understand this you should avoid the new keyword all together.
Edit: to answer what it means? it means you allocate a board object then dereference it and save a new copy in your variable gameBoard. Essentially giving you two copies of the Board object.
new board(givenX,givenY,givenMineCount); in a nutshell, performs two things: creates a board object in memory and returns the address where it was created.
In your second statement, gameBoard is a stack variable that holds a board object. As I mentioned before, the new returns an address and by using the * operator, you're basically "interpreting" (the actual technical term is dereferencing) the address as a board. That said, doing this seems to be making a copy and assigning it to boardGame and leave lingering in memory what was created with new.
I'm new to c++, but I think extra details are missing here for beginners like me and like the asker.
Note: This answer contains details for newbies like me.. advanced c++ developers may find this post somewhat confusing!
Lazy? tl;dr at the end
Does always creating and object with *new creates two copies of objects? (one will never ever be deleted)
Lets check this out:
As explained by others, the *new is just a shortcut to new in one statement and then dereference it with the asterisk operator (*)
Consider the following struct that holds a single number:
struct myStruct
{
public:
myStruct() { innerNumber = 0; }
myStruct(uint16_t num) {
innerNumber = num;
}
uint16_t innerNumber;
};
Lets create a SINGLE object, and dereference it MULTIPLE times:
myStruct* obj = new myStruct();
myStruct obj1 = *obj;
myStruct obj2 = *obj;
myStruct obj3 = *obj;
obj1.innerNumber = 1;
obj2.innerNumber = 2;
obj3.innerNumber = 3;
printf("%d-%d-%d\n", obj1.innerNumber, obj2.innerNumber, obj3.innerNumber);
prints: 1-2-3
Pretty cool =] (and dangerous)
So, if we get it correctly, it is ALWAYS a bad idea to use *new as already mentioned here, it will always cause a memory leak!!
lets see it in action:
while (true) {
myStruct& inner = *new myStruct();
delete &inner;
}
That code should:
enter an infinite while loop
allocate a new myStruct object
dereference it (causing it to be copied!)
delete the copy only
Or in shortly: A MEMORY LEAK
Well, I'm running this, and the memory isn't increasing!
*new is GOOD when creating a reference. You can see that I defined
a ref type by the & operator (myStruct& inner)
Another problem that may arise (and is general for references) is that:
// Create a reference
myStruct& inner = *new myStruct();
inner.innerNumber = 0;
// WHAT WILL HAPPEN HERE?
myStruct whatAmI1 = inner;
myStruct whatAmI2 = inner;
whatAmI1.innerNumber = 1;
whatAmI2.innerNumber = 2;
printf("Original: %d Copies: %d-%d\n", inner.innerNumber, whatAmI1.innerNumber, whatAmI2.innerNumber);
prints: Original: 0 Copies: 1-2
dangerous!
TL;DR
*new is bad for creating value types
*new is good for creating reference type
Be careful when assigning a reference type to a value variable, it
makes a copy

Program crashes when deleting a pointer pointing to the heap?

If I go...
int *foo = new int;
foo += 1;
delete foo;
Most of the time it crashes. Is there a reason for this? I'm trying to have the pointer point one spot forward (4 bytes). Thanks.
Edit (six months later): This was the first question I asked on SO, and it was a silly question and deserved the downvotes. It can be deleted if it's of no use to learners. I was indeed talking about allocating an int of four bytes on the heap, then moving the pointer four bytes forward, and then deleting the int pointer, essentially deleting God knows what, leading to undefined behaviour. Thanks for your help.
The only thing you can safely pass to delete is something you got when you called new, or nullptr, in that case the delete won't do anything.
You changed the value of the pointer - therefore it isn't "something you got when you called new"
You must pass to delete the value that new returned. You don't do that.
I think that you are confused as to what you are passing to delete. I think that you believe that delete foo will delete the memory associated with the variable. It doesn't. It deletes the memory whose address is stored in foo.
As an example, this is legitimate:
int* foo = new int;
int* bar = foo;
delete bar;
What matters is not the name of the variable, but rather the value of the variable.
Here's another example:
int* arr = new int[10];
int* ptr = arr;
for (int i; i < 10; i++)
{
*ptr = i;
ptr++;
}
delete[] arr;
In order to perform pointer arithmetic, and retain the address returned by new[], we introduced an extra variable. I used an array because it doesn't make sense to perform arithmetic on a pointer to a single value.
Note that in the code above, it could be written more clearly using arr[i] = i and so avoid the need for a second pointer variable. I wrote it as above to illustrate how you might code when pointer arithmetic is the right option.

Difference between int someInts[3] and int* someInts = new int[3]?

What is the difference between declaring a new integer array by using int someInts[3], versus using int* someInts = new int[3]?
There are 2 main differences:
The first will allocate a memory on the stack, that will be unavailable once the function returns.
The second will allocate a memory on the freestore, which will be available until deleted.
The first someInts is an array of ints, you cannot assign new address to it.
The second is a pointer to int, so you may assign a new address to it.
The difference that's generally important (especially when you're dealing with something other than ints) is that with when you use the latter (int *someints = new int[3];) you have to explicitly delete the data when you're done using it.
Most of the time, you want to use std::vector<int> someints(3); instead. This will (normally) allocate the space for the data similarly, but it'll automatically delete that space when the variable goes out of scope (including, for example, leaving the scope via an exception being thrown, which is much more difficult to handle correctly when you allocate/free the memory manually).
Declaring int* someInts = new int[3] allocates the memory on the heap. Declaring int someInts[3] allocates it on the stack.
When you do someInts[3], you allocate memory on the stack, this means that it will delete itself (good) but if you want to access after the function has ended you'll run into trouble as it will already have been deleted. IE:
int* returnPointerThingy(){
int someInts[3];
someInts[0] = 3;
someInts[1] = 2;
someInts[2] = 1;
return someInts
}
This will return a null pointer since someInts has been deleted. If you try to access something in someInts god help you.
If this is similar to what you which to do you want to use the new keyword. It will allow you to allocate something on the "Heap" and it will live after the function it was declared in has ended. Thus this:
int* returnPointerThingy(){
int* someInts = new int[3];
someInts[0] = 3;
someInts[1] = 2;
someInts[2] = 1;
return someInts
}
Will not return a null pointer and you will be able to use the values stored by someInts. However this comes with a drawback, you must delete someInts like this:
delete [] someInts
So you don't end up with memory leaks, when the heap gets taken up by pointers and such.
It depends on your situation for which to use as both are better in their own situations.

C++ filling an array with numbers then returning a pointer to it

Ive been faced with a problem recently that I can't think of a good way to solve. I'm using a case structure to attempt to set attributes to a "character" that will be passed to an object constructor.
Example:
//note this is inside a function with a return type of int*
int selection;
cin >> selection;
int * iPtr;
switch(selection){
case 1:{
int anArray[6] = {8,5,2,4,250,100} // str, dex, int, luck, hp, mp
iPtr = anArray;
return iPtr;
}
//more cases and such below
The issue that I'm having is that when I return my pointer it seems to be filled with a good amount of junk, rather than the information, rather than the information that I would be expecting it to hold. Is that because the array gets destroyed at the end of the scope? If so what should I do to make this work out how I'm hoping for it to (getting a pointer with the values that I want).
Thanks!
Yes - anArray is declared on the stack. When the function exits, its stack frame is reclaimed, so it's no longer valid to refer to that memory. If you want the array to persist, allocate it on the heap instead:
int* anArray = new int[6]; // and initialize
return anArray;
Just remember to clean it up later at some point with the corresonding delete[].
EDIT
You should prefer to use something that automatically manages resources for you, like in Praetorian's answer, so that you don't accidentally leak memory.
Yes, the array you've declared is indeed local to the function and no longer exists once the function exits. You can dynamically allocate an array using new and then have the caller delete[] the memory (but don't do this!), or modify your function to return an std::unique_ptr instead of a raw pointer.
unique_ptr<int[]> anArray (new int[6]);
// do initialization
return anArray;
Now, the caller doesn't have to worry about freeing memory allocated by the function.
EDIT:
There are a couple of different ways to perform initialization of the unique_ptr.
anArray[0] = 8;
anArray[1] = 5;
// etc ...
OR
int init[6] = {8,5,2,4,250,100};
std::copy( &init[0], &init[0] + 6, &anArray[0] );
Yes, it's because the local array is overwritten as the program runs. You can either declare the array static in the method (which would be a good idea for a fixed array like this), declare it at global scope, or allocate an array with new to return. The last alternative gives you the opportunity to have a different array returned for each call, but remember to deallocate the arrays after use.
In C++, the best answer is not to return a pointer. Instead, use a proper object instead of a C array or manually allocated memory and return this object:
std::vector<int> f() {
std::vector<int> array;
// fill array
return array;
}
Using new int[x] (or whatever) is really, really deprecated in modern C++ code and is only deemed acceptable under very special circumstances. If you use it in normal code, this is a very obvious place for improvement. The same goes for other uses of manually managed memory. The whole strength of C++ lies in the fact that you don’t have to manage your own memory, thus avoiding a multitude of hard to track bugs.
Yes, it is because the array you created is created on the stack, and when you return, the part of the stack that you were at is overwritten (presumably by a debug process).
To avoid this, you would write
int* anArray = new int[6];
// fill the array
return anArray;
In this case, you will also have to delete the returned result when you are finished with it, such as in
int* dataArray = getTheArray();
// Use the dataArray
delete [] dataArray;
Allocate array on the heap
int* anArray = new int[6];
You will have to delete it manually:
delete[] iPtr;

Return pointer to data declared in function

I know this won’t work because the variable x gets destroyed when the function returns:
int* myFunction()
{
int x = 4;
return &x;
}
So how do I correctly return a pointer to something I create within the function, and what do I have to take care with? How do I avoid memory leaks?
I've also used malloc:
int* myFunction2()
{
int* x = (int*)malloc(sizeof int); *x = 4; return x;
}
How do you correctly do this - in C and C++?
For C++, you can use a smart pointer to enforce the ownership transfer. auto_ptr or boost::shared_ptr are good options.
Your second approach is correct. You just need to clearly document that the caller "owns" the result pointer, and is responsible for freeing it.
Because of this extra complexity, it is rare to do this for "small" types like int, though I'm assuming you just used an int here for the sake of an example.
Some people will also prefer to take a pointer to an already allocated object as a parameter, rather than allocating the object internally. This makes it clearer that the caller is responsible for deallocating the object (since they allocated it in the first place), but makes the call site a bit more verbose, so it's a trade-off.
For C++, in many cases, just return by value. Even in cases of larger objects, RVO will frequently avoid unnecessary copying.
One possibility is passing the function a pointer:
void computeFoo(int *dest) {
*dest = 4;
}
This is nice because you can use such a function with an automatic variable:
int foo;
computeFoo(&foo);
With this approach you also keep the memory management in the same part of the code, ie. you can’t miss a malloc just because it happens somewhere inside a function:
// Compare this:
int *foo = malloc(…);
computeFoo(foo);
free(foo);
// With the following:
int *foo = computeFoo();
free(foo);
In the second case it’s easier to forget the free as you don’t see the malloc. This is often at least partially solved by convention, eg: “If a function name starts with XY, it means that you own the data it returns.”
An interesting corner case of returning pointer to “function” variable is declaring the variable static:
int* computeFoo() {
static int foo = 4;
return &foo;
}
Of course this is evil for normal programming, but it might come handy some day.
C++ approach to avoid memory leaks. (at least when You ignore function output)
std::auto_ptr<int> myFunction() {
std::auto_ptr<int> result(new int(4));
return result;
}
Then call it:
std::auto_ptr<int> myFunctionResult = myFunction();
EDIT: As pointed out by Joel. std::auto_ptr has it's own drawbacks and generally should be avoided.
Instead std::auto_ptr You could use boost::shared_ptr (std::tr1::shared_ptr).
boost::shared_ptr<int> myFunction() {
boost::shared_ptr<int> result(new int(5));
return result;
}
or when use C++0x conforming compiler You can use std::unique_ptr.
std::tr1::unique_ptr<int> myFunction() {
std::tr1::unique_ptr<int> result(new int(5));
return result;
}
The main difference is that:
shared_ptr allows multiple instances of shared_ptr pointing to the same RAW pointer. It uses reference counting mechanism to ensure that memory will not be freed as long as at least one instance of shared_ptr exist.
unique_ptr allows only one instance of it holding pointer but have true move semantic unlike auto_ptr.
In C++, you should use new:
int *myFunction()
{
int blah = 4;
return new int(blah);
}
And to get rid of it, use delete:
int main(void)
{
int *myInt = myFunction();
// do stuff
delete myInt;
}
Note that I'm invoking the copy constructor for int while using new, so that the value "4" is copied onto the heap memory. The only way to get a pointer to something on the stack reliably is to copy it onto the heap by invoking new properly.
EDIT: As noted in another answer, you will also need to document that the pointer needs to be freed by the caller later on. Otherwise you might have a memory leak.
There is another approach - declare x static. In this case it will be located in data segment, not on stack, therefore it is available (and persistent) during the program runtime.
int *myFunction(void)
{
static int x = 4;
return &x;
}
Please note that assignment x=4 will be performed only on first call of myFunction:
int *foo = myFunction(); // foo is 4
*foo = 10; // foo is 10
*foo = myFunction(); // foo is 10
NB! Using function-scope static variables isn't tread-safe technique.
Your second code snippet is correct.
To help avoid memory leaks, I let the coding conventions help me.
xxxCreate() will allocate memory for xxx and initialize it.
xxxDelete() will destroy/corrupt xxx and free it.
xxxInit() will initialize xxx (never allocate)
xxxDestroy() will destroy/corrupt xxx (never free)
Additionally, I try to add the code to delete/destroy/free as soon as I add the code to create/init/malloc. It's not perfect, but I find that it helps me differentiate between items that need to be freed and those that don't, as well as reducing the likelihood that I will forget to free something at a later time.
Boost or TR1 shared pointers are generally the way to go. It avoids the copy overhead, and gives you semi-automatic deletion. So your function should look like:
boost::shared_ptr<int> myFunction2()
{
boost::shared_ptr<int> x = new int;
*x = 4;
return x;
}
The other option is just to allow a copy. That's not too bad if the object is small (like this one) or you can arrange to create the object in the return statement. The compiler will usually optimize a copy away if the object is created in the return statement.
I would try something like this:
int myFunction2b( int * px )
{
if( px )
{
*px = 4;
return 1;
}
// Choice 1: Assert or Report Error
// Choice 2: Allocate memory for x. Caller has to be written accordingly.
// My choice is 1
assert( 0 && "Argument is NULL pointer" );
return 0;
}
You're asking how to correctly return a pointer. That's the wrong question, because what you should be doing is using smart pointers rather than raw pointers. scoped_ptr and shared_ptr (available in boost and tr1) are good pointers to look at (e.g. here and here)
If you need the raw pointer for something (e.g. passing to a C function), the get() method will supply it.
If you must create raw pointers, e.g. for homework, then you can use malloc() (as you did) or new within a function, and hope you remember to de-allocate the memory (through free() and delete respectively) Or, in a slightly-less-likely-to-leak idiom, you can create the pointer with new, pass it to a function, and de-allocate with delete when you're done with it. Again, though, use smart pointers.