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
Related
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.
Ok, here i have 2 simple C++ examples, the first one is:
MyClass
class MyClass
{
private:
int test;
public:
int member(){
test = 456;
return 1;
} // one public function
};
global function definition
int funct(MyClass** obj)
{
*obj = new MyClass();
int c = (**obj).member();
return 1;
}
main
...
MyClass* object;
int i = funct(&object);
...
while in the second case, i modify the main like this:
MyClass** object = (MyClass **)malloc(sizeof(MyClass));
int i = fun(object);
Both examples work fine, but i'm not sure if i understood correctly why ONLY in this second case i need a malloc (otherwise it wouldn't compile at all).
Thanks in advance for your help
PS: i know double pointers are more C-style programming, but i'm currently experimenting with both languages.
MyClass** object = (MyClass **)malloc(sizeof(MyClass));
actually this is wrong, malloc will return pointer to allocated memory: MyClass *, so if you later do: *object and would like to see a pointer to MyClass you will be wrong. You should rather:
MyClass* pobject = (MyClass *)malloc(sizeof(MyClass));
MyClass** ppobject = &pobject ;
your question is unclear to me - sorry,also it is not wise to allocate clases with malloc - your one looks like its POD - so it seems to be safe, but I would check it with std::is_pod.
[edit]
working example is below. You asked why you need initialization of object in the second case, thats because in first case you reserve storage for your pointer by simply defining pointer variable : MyClass* object;. Here object can be safely used in funct. In second example, you dont have reserved memory (in this case space on stack) for your pointer to MyClass, so you must allocate it with malloc or new. Hopefully thats clear enough.
MyClass** object = (MyClass **)malloc(sizeof(MyClass*));
//MyClass** object = new MyClass*;
int i = funct(object);
delete *object;
free(object);
//delete object;
First of all, you have a bug (and the whole thing works only because sizeof(MyClass)>=sizeof(MyClass*)):
MyClass** object = (MyClass **)malloc(sizeof(MyClass));
is incorrect, should be
MyClass** object = (MyClass **)malloc(sizeof(MyClass*));
or
MyClass** object = new MyClass*;
Second, you do need malloc() (or new) because you need your double pointer MyClass** to point to some instance of MyClass*. Your first and second (after correction) example differ only in a way where you get this MyClass* - in first example it is on-stack, in second example it is on heap.
Oh, and when it on heap, you need to manually call free() (if malloc() was used to allocate it) or delete (if new was used) for the pointer.
I deleted my previous answer. This is how you should go about initializing the double pointer:
MyClass** object;
object = new MyClass*;
int i = funct(object);
The second line allocates a new pointer to an instance of MyClass, and the call to funct allocates an actual object of MyClass. After this call, object will point to a valid pointer to a valid instance of MyClass.
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.
I am experimenting with Struct, pointers and typedef in the code below. I want to create a pointer to a struct that I made up. Then I want to manipulate the struct's members using the -> operator.
The below code compiles fine, however, when I run the program it produces a segmentation fault.
Can someone please help explain where my logic went wrong?
Thank you.
struct Structure1 {
char c;
int i;
float f;
double d;
};
typedef Structure1* structp;
int main(){
structp s1, s2;
s1->c = 'a';
s1->i = 1;
s1->f = 3.14;
s1->d = 0.00093;
s2->c = 'a';
s2->i = 1;
s2->f = 3.14;
s2->d = 0.00093;
}
structp s1, s2;
You've declared two pointers, s1 and s2 but they don't point anywhere yet! You need to allocate memory for these pointers using new.
s1 = new Structure1();
s1->c = 'a';
s1->i = 1;
// ...
Don't forget to delete the memory afterwards:
delete s1;
See this answer why the parentheses in new Structure1() make a difference. Also, note that there are other ways to obtain a pointer to an object, such as using the & operator, but in this particular case, I think you want to allocate memory.
Pointers are objects in memory that point to another object. When using the indirection operator it causes the pointer to be dereferenced. For example, this:
s1->c;
is the same as:
(*s1).c;
When you dereference a pointer, it returns a reference to the object that it points to. If there is no object that it points to (or it points to nullptr), deferencing it gives your program Undefined Behavior.
The solution would be to create a new instance of a class on the heap and return a pointer to it. That is what new does:
Structure1 *structp = new Structure1();
It makes sense once you realize that pointers are not the actual objects, they are simply memory addresses. If you don't allocate space or assign to it a memory address, it will remain uninitialized and filled in with garbage. Just like a regular object, why would you want to use an initialized pointer?
I was wondering how to write the operator = so that the existing allocated memory on a variable be deallocated.
For instance, in the code below, when reassigning the x pointer x = new ClassExample(4), the old x->a memory would be deallocated.
Apparently, when using new, the operator = doesn't apply (it's only for already existing values).
Is there any method of doing this (free old memory when alloc new memory)?
#include <iostream>
#include <cstdlib>
class ClassExample {
public:
int* a;
ClassExample& operator= (const ClassExample& rightSide) {
//.....
}
ClassExample(int val) {
a = new int(val);
}
};
int main()
{
ClassExample* x = new ClassExample(2);
x = new ClassExample(4);
return 0;
}
Never break this rule: every new has to be balanced with a delete.
You could use a smart pointer to achieve what you want, or, in your specific case something simpler:
Briefly, you build a WrappedPtr<T> template class for data type T, which holds a T* pointer. As a starting point, you can define an assignment operator which will delete a currently wrapped object before taking the new one as its member data. You will need to take care with copy construction; or even forbid it.
A true smart pointer will also implement reference counting in some way.
See http://www.boost.org/doc/libs/1_54_0/libs/smart_ptr/shared_ptr.htm
The operator= means you are changing the value inside your current object.
Here, you are just changing the pointer x.
The way you could do it is :
ClassExample x(2);
x = ClassExample(4);
Or, in your case, something like:
ClassExample* x = new ClassExample(2);
*x = *(new ClassExample(4));
This last one will introduce leak in your program, so do NOT use it.
Of course, you can use something in between, like:
ClassExample* x = new ClassExample(2);
*x = ClassExample(4);
This one won't leak.