**So recently i came up with a question in an interview it was based on pointers**
void fun(int *p){
int q = 10;
p = &q;
}
int main() {
int r = 20;
int *p = &r;
fun(p);
cout<<*p<<endl;
}
*my question is
(1)Justify the result w.r.t the memory allocation like how this is happening?;
(2) how to pass this pointer variable by refrence (i wrote *&p in the parameter of void fun()) when i did it i observed that the p is printing a garbage value ,Now first i thought may be fun has different memory allocation and when it takes the address of q from fun function it address changes but that address in main function is pointing to some garbage value ,Am i right and please explain?
void fun(int *&p) {
int q = 10;
// here the object q began its existence
p = &q;
// here you pass the address of that object *out*
// of the function, to the caller
// here the object q ceases to exist
// question: does anyone have now-invalid pointers that
// pointed to that object?
}
You'll of course immediately see that yes, the caller of fun has a pointer that doesn't point to a valid object (objects that don't exist are by definition invalid). This is undefined behavior. Anything can happen.
Whatever you observe is just as good as what anyone else would observe :) I can make this code pretend to work, or pretend fail on almost any compiler - it's only a matter of arranging things in a certain way. That doesn't make the code any more valid, of course, and the notion of "working" or "failing" is meaningless anyway: the code is invalid, so as far as C++ is concerned, the discussion about the effects is invalid as well :)
Related
I have read that dangling pointers are bad as they point to location that is supposed to be free.But I don't understand why is that bad?So can you give me any example of disadvantages of dangling pointer.
Once you have a dangling pointer, two things are forbidden:
You are not allowed to dereference the pointer. The behaviour on doing so is undefined.
You are not allowed to read the pointer. It's as if the pointer is an uninitialised variable, or one you've just declared.
Few folk tend to fully grasp (2), and are surprised the first time they find out about this!
As such, dangling pointers can compromise program stability. And that's quite a disadvantage.
A dangling pointer is a pointer that points to a location in memory where there was an object but that object is already gone.
A dangling pointer is nothing useful or desirable, it rather describes that the pointer is completely useless and you probably have a logic error in your code.
Consider this:
int* x;
{
int y = 4;
x = &y;
}
*x = 42; // BOOOM !! Dont do this !! Undefined behavior !!
After closing the scope (}) the object x points to does no longer exists. x will not automagically be set to NULL or anything the like. There is no y at the memory location x was pointing to. The official terminology is that after closing the scope x has a invalid pointer value in C++ and in C the value of the pointer is indeterminate.
On the other hand, if you do not dereference x after y is gone, there is no problem. x is still a dangling pointer but you can simply assign something else to make it point to some object again:
int* x;
{
int y = 4;
x = &y;
} // <- x can be said to be dangling here, but who cares?
int z = 5;
x = &z; // <- x again points to an object
Dangling pointer is risky because once allocated memory has been freed, it can be reclaimed by other allocations.
Consider this example:
int main(int argc, char *argv[]) {
int *p = (int *) malloc(sizeof(int));
free(p);
*p = 5;
printf("%d\n",*p);
}
Once p is freed, there is no guarantee that 5 will be printed anymore. Also, If we write to p's address, we might be overwriting some other value used in another part of your program and trigger segmentation fault.
I have some questions about pointers, scopes and pointers inside vector encapsulated in class
i have this supposed cases and examples with questions:
Example 1
the variable int y scope is inside the function and when the function finish and go away that returning reference will be died and that reference be referenced to nothing?
int& createInt() {
int y = 5;
return y;
}
case1: if i do this in main or other function:
int x = createInt();
std::cout << "x value \n";
std::cout << x << "\n";
// std::cout return 5
this mean that im saving my own copy of the value of createInt()
function that is 5 in the variable x, so is safe because int x contain their own value?
but what happen with the reference returning from the createInt() function, is there a memory leak or not because is not a pointer a will die with the scope of the function.
case 2: if i do this in main or other function:
int &x = createInt();
std::cout << "x value \n";
std::cout << x << "\n";
// std::cout return 32767
int &x is equals to the reference returning from createInt() function, that reference die when the function finish/go away so for that reason
int &x is returning a wrong value 32767 and not 5 or what are that 32767 value?
so int &x = createInt(); is evil and very bad practice because is reference to nothing.
example 2
what about this? i'm requesting allocation memory for int and initialized memory to the pointer variable...
int& createInt() {
int* y = new int(5);
return *y;
}
that pointer variable is in the stack but store a reference to the new int that is in the heap, so that new int will be alive when the scope of the function go away because is in the heap right?
so when i return the reference i'm returning the reference to that new int not the pointer variable, right? so is bad to returning the reference instead of the pointer? for what?
case1: if i do this in main or other function:
int x = createInt();
std::cout << "x value \n";
std::cout << x << "\n";
// std::cout return 5
i'm creating a copy of the new int value from createInt() in my local int x variable, so is this a memory leak because i'm creating a copy and not getting the pointer, so i can't do a delete of int x variable because is not a pointer, and also i can't delete the int *y pointer created inside createInt() function because the pointer is lost, i don't have it outside the createInt()
but whats happen if i do:
delete &x;
i will get a error:
malloc: *** error for object 0x7ffee204b8c8: pointer being freed was not allocated
because i'm deleting my int x that is not in the heap? or is trying to delete the int *y inside the createInt() function ?
case2: if i do this with the same function:
int &x = createInt2();
std::cout << "x value \n";
std::cout << x << "\n";
// std::cout return 5
my int &x is a reference of the returning by createInt()
so i can do:
delete &x;
is a memory leak here? but its so bad delete &x reference instead of the pointer int *y? maybe doing delete & i'm not have form to be sure if that is allocated memory or is stack memory, so good practice is never try to delete using &?
vectors parts:
i have a class A that contain a vector of pointers of class B, also i have a method that return a element of the vector but as reference (because i want to have it in memory to reutilize it and control when is deleted like a connection pool also i move it from used vector to notInUsevector but this is other history), and in the destructor of class A i delete all the vector elements:
Class A {
//this is singleton
public:
static A& getInstance()
{
std::call_once(m_once, []() {
instance.reset(new Database());
});
return *instance;
}
B& getFirstElement() {
auto element = connections.front();
return *element;
}
~A() {
for(auto element : myVector){
delete num;
}
}
A(A const &) = delete;
void operator=(A const &) = delete;
private:
A();
static std::unique_ptr<A> instance;
static std::once_flag m_once;
std::vector<B*> myVector;
}
so in other place/function/class etc i do:
auto element = &A::getInstance().getFirstElement();
or maybe is best or the same:
auto &element = A::getInstance().getFirstElement();
so when the Class A instance is deleted the destructor will delete all the pointers inside myVector
is this safe, there is a memory leak? it's a very bad return the reference in the getInstance() function instead of the pointer?
thanks
First of all let's make it clear, scope is "layer" between { and }. It might be a function body, statement (if, switch, for, etc.) or standalone scope. The most important consequence is that life time of objects created on stack is limited to that scope.
Take your function createInt() as example, internal int y, exists only inside of that function. The moment you reach } that memory is free.
Second thing is term memory leak. Memory leak is a situation where you have a chunk of memory (might be a single byte, might be a couple of pages) and no way to point at it. It's like a locked box without a key. It is there, it is yours memory, it won't be free unless you tell, problem is you don't know where that memory is located, you have no pointer for it.
That's being said, let's talk about your cases:
Example 1 Case 1:
You are lucky. Your function return its internal y by reference, but this returned variable is freed before you return from your function. Effectively you have a value written down on sticky note, then you throw it to the trash and then return saying that your value is on that note that is in trash. The only reason you can still read it is because no one assigned that bit of memory in the mean time and it was not overwritten. Remember, the moment your function reached } all stack alocated variables (y was allocated on stack) are destroyed. That also answer your second question about memory leak, there is no memory leak. As long as you work with stack, allocation and deallocation is done "automagically" as destructor calls are inserted at the end of the scope (usually) by compiler.
Example 1 Case 2:
The very same thing as in case 1. Your returned value is compromised because you returned stack allocated variable that is no longer valid as you return from function. Now you can observe this because between assigning and reading that value you make a function call. Depending on where original y was allocated that bit of memory might be reused during std::cout call. This become obvious as you work on the very same bit of memory cause of reference usage. Remember when you reached } of createInt(), you free that bit of memory. As an additional excersise, put a break point on lines int &x = createInt(); and int x = createInt(); then step into function and watch memory state as you leave it.
Example 2 Case 1:
Now you create (potential) memory leak. You allocate a memory on heap so it won't be destroyed as you leave function body. You also pass that exact memory address, so you also should take responsibility for freeing it and you don't call delete, so that's your memory leak. And one more problem occurs as you assign returned value to completely new stack allocated variable. Your original x from createInt() is allocated, then returned by reference but feed to assign operator to other independent variable (int x have different address than int* y). Again you can check this with help of breakpoints and debugger.
Example 2 Case 2:
Now this is almost proper use of variables returned by reference and assignment of them. You create variable x on heap, then return it's address and assign it to y. Problem being as x was created on stack you are responsible for destroying it so call to delete is neccessary to avoid memory leak. Put a break point and track memory addresses of both x and y. They are the same.
General rule of thumb is that return by reference should be used only with variables that exist outside of function, for example you can use it for class memebrs as they live inside the object or for global or static variables. For other purposes use return by value, unless you really need that very object, then return it by pointer. And while you work with pointers always be aware that someone at some point have to delete underlying variable.
I skip the part about vectors and instead point you a good tool for tracking memory leaks. It's not the best solution by any means, but for starters it will do the trick (assuming you are using Visual Studio).
https://learn.microsoft.com/pl-pl/visualstudio/debugger/finding-memory-leaks-using-the-crt-library?view=vs-2019
Remember to use breakpoints and debugger instead of printing everything to output/console. This will help you a lot. In both tracking memory and variable state, and understanding what your code really does.
I don't have the impression you have a real question at all, because you seem yo have found out all tricks, traps and good practices on your own. You seem to know about memory leaks and dangling references. Static and dynamic allocation. Most of your assumptions seem correct. Some hints though :
* references '&' and raw pointers result in exactly the same machine instructions, but they are hints to the programmers. Indeed, a method returning a reference likely means you don't have to take ownership for that reference, but without documentation there is no guarantee on the lifetime of that object. A raw pointer may represent a heap instance, or an optional argument, but it could also represent just a reference. This lack of ownership rules in C/C++ is indeed tricky.
* When dereferencing a dangling reference, the behavior is undefined. It may be working perfectly on your machine and it could burn my harddisk. Anything goes.
* When dealing with heap allocations, we nowadays prefer yo use smart pointers whenever possible. There is no mistaking in it's usage. Search for unique_ptr and shared_ptr
* Finally I recomy learning a bit of Rust. This is a programming language that was specifically designed to resolve such object lifetime/ownership issues. It is quite easy to install and run the most basic examples. Just try returning a dangling reference with Rust, you'll learn a lot, believe me.
I'm very new to C++ (and studying Java). This is from HW but I think I've answered the HW issue and I'm just trying to get a better sense of pointers.
Say I have the following method:
int cubed(int a) {
int * ptr;
*ptr = a * a * a;
return *ptr;
}
This compiles and works fine with the following:
int test = cubed(3);
I'm trying to get a sense of why it's bad to return a dereferenced pointer.
This question says that memory leak is a problem but I'm not sure why. Maybe because I don't understand what happens to a dereferenced pointer.
Does the lvalue just hang around indefinitely at that point? Do you have to actually delete the pointer? Any insight would be appreciated.
The question you read is different. Say you had this code:
int cubed(int a) {
int* ptr = new int;
*ptr = a * a * a;
return *ptr;
}
Now, you'd be leaking the dynamically-allocated int, because you'd return a copy of it and never delete the original.
Your code is actually worse because, instead of allocating with new, you're simply writing through an uninitialised pointer to memory that is not yours. In effect, you're writing to an int that does not exist.
What you should be doing is this:
constexpr int cubed(const int a)
{
return a*a*a;
}
Or just invoke std::pow(value, 3) at the call site.
There is no memory link in your code, but there is another big bug.
You declare int * ptr; inside the function int cubed(int a), so it is a local variable.
The value of ptr will be random - might be NULL, might point to garbage, might point to some perfectly valid address. You don't initialize the variable ptr, so your code will sometimes crash.
int* func(int *ptr)
{
static int a = 5;
ptr = &a;
return ptr;
}
Someone asked me this question in an interview. Now the point is, the variable 'a' is static, so, unlike ordinary variables which are declared, which loses it's value (popped from stack) once the function returns, this variable retains it's value as it is a static one.
Then i didn't understand, what's the issue with this piece of code?
There is no point in having ptr as a parameter. The passed value is not used. You could change this to
int* func()
{
static int a = 5;
return &a;
}
There is no issue. a is static so it exists through the lifetime of the execution. It is syntactically invisible outside func. You are just returning the address of some "hidden" global variable.
The value (address you're pointing to) of ptr that you are passing in is NOT changing outside the function as you are changing a locally scoped copy of ptr
It needs to be passed in by reference or pointer to pointer for it to change.
int* func(int **ptr)
{
static int a = 5;
*ptr = &a;
return *ptr;
}
I'm bringing back your attention for local static variables. All time the variables will be remain same from last call. So, if you increase the variable a=a+1 then next time the value is remain 6. Here come how it happens. Each local declare new space in memory in each call. But in static variable you are telling to use same memory for every time. So, pointer will remain same. That why you are getting same address. This is not unexpected.
There isn't an issue, unless the caller doesn't understand what the function does. This is quite possible, given that people may assume the function modifies the value pointed to by the parameter.
For instance, if somebody writes code like
int foo = 0;
func(&foo);
assert(foo == 5);
They will have an issue.
The interviewer may have been looking for a solution like:
int *func(int *ptr) {
static int a = 5;
*ptr = a; //modify value being pointed to by argument
return ptr;
}
There is a thread-safety issue: returning a non-constant pointer to a makes it possible that some thread will modify the value while another thread is reading it. Data races have undefined behavior.
I'll also toss in that returning a raw pointer is horrible practice, since I haven't seen it in the other answers. int& func() should be preferred.
Okay i've seen this done somewhere before where you have a function that takes a pointer parameter and returns a pointer.
However you can choose not to pass a parameter and it will return a dynamically allocated pointer but if you do pass a pointer then it just fills it in instead of creating one on the heap. This is a single function not overloaded.
My question is how is this safely done?
I had a guess it was something like this:
point* funct(point *p = some_value)
{
if p == some_value
//create a point *p on the heap
else
//create use the given *p and fill it in
return p
}
Now i can't think if this is right way to do it and if it is then what could be a good some_value? it can't be NULL because when you pass empty pointer it will also be NULL and not sure if it is safe to have it greater than 0. Also you can't have negative numbers on pointers either, so whats a good safe value?
Any good way to do this that is also PORTABLE across platforms?
EDIT:
Okay maybe i didn't explain properly basically i want the function to be used like this:
point *x;
point *y;
x = func();
func(y);
Not
x = func(NULL);
if I use NULL i get an error segmentation fault only when i do func(y);
The reason for this is:
either the user passes a pointer he manages such as one created on the stack OR the function will give a dynamic one back if none is given. I don't want to force the return of only dynamic memory or only accepting a pointer to fill.
I know I have seen this done somewhere before.
Normal solution is to have 'if NULL allocate' - that's what 'c' realloc does.
It looks like you want to have a function that uses existing memory if provided or else allocates it's own.
It's not clear what you should return if you are passed a valid pointer.
Should it return that pointer?
Or should it be null to ensure that there aren't two copies of pointers to the same bit of memory - which will cause problems if they are freed.
It might be safer to pass a **pointer into the function and require an argument - even if that arguement is a pointer to null.
Well obviously if a someone ever was to call funct(NULL) then it would result in a crash anyway. so why not have some_value=NULL so to make
if(p==NULL){
p=dynamic_memory;
}
where dynamic_memory is allocated in the constructor(not thread-safe!) or replace dynamic_memory with a call to new
Edit:
Or. If you must have 3 states in your function, one for if no argument is supplied, one for if a valid pointer is passed, and one for if NULL is passed, then you can use pointer-to-pointers.
like
void *func(void** p=NULL){
if(p==NULL) ...//user supplied no argument
if(*p==NULL) ...//user supplied NULL
else //user supplied valid pointer
This doesn't seem to be what you want however and then people would have to pass pointers with '&' to your function.. (is &NULL even valid?)
My guess would be more along the lines of:
point* funct(point *p = NULL)
{
if (p == NULL) {
// create a point *p on the heap
// and use it
return(p);
}
else {
//use the given *p and fill it in
return(NULL);
}
}
Not too sure about having the possibility of the pointer to your point object passed in though. Could be quite hard to check for, and checking the type of an object passed in, i.e. "looking under the covers" using RTTI, is not the best OO practice.
You get an error when you call func(y) because y is not initialized. It contains random bits that point to a random location in memory. You need to initialize y to NULL.
point *x, *y;
x = func();
y = NULL;
y = func(y); // so it can be deleted later you need to assign the return value
delete x;
delete y;
Why not do this? And avoid the heap allocation completely.
point x, y;
func(&x);
func(&y);
Or:
point *x;
point *y = new point();
x = func();
func(y);
delete x;
delete y;
As I said in the comment above, memory ownership is confusing in your function. Functions that dynamically allocate their results should do so every time or none of the time. When they do so some of the time, the potential for a memory leak is much higher.
Personally, I would go even further and avoid all allocations, pass by reference:
void func(point& p)
{
//do stuff
}
point x, y;
func(x);
func(y);
something like this:
T* func(T* p) {
if(!p) {
p = new T;
}
// do whatever with p
return p;
}
then you can either do:
T* x = func(NULL);
// whatever
delete x;
or:
T x;
func(&x);
EDIT:
There is a non-thread safe option which several libraries use. Basically it works like this:
T* func(T* p) {
static T buf;
if(!p) {
p = buf;
}
// do whatever with p
return p;
}
then you can either do:
T* p = func(NULL);
or:
T x;
T* p = func(&x);
There are often "reentrant" versions of these as well which are often tied to the non-thread safe versions like this:
T* func(T* p) {
// behaves as above example, except now we can
// use func_r in a thread safe way if we need to
static T buf;
return func_r(p, buf);
}
T* func_r(T* p, T *buf) {
if(!p) {
p = buf;
}
// do whatever with p
return p;
}
You have to ask yourself why passing NULL us giving you a seg-fault. It is certainly not because NULL is not an appropriate value, it will be caused by whatever your code does when NULL is passed. However you chose not to show that code.
Haver you stepped through this code in your debugger?
Apart from that, in C++ do not use NULL. It is a macro and open to incorrect redefinition. Use plain zero (0). The language places guarantees that a zero literal constant when converted to a pointer will not be a valid address. The chances are that your NULL macro is in fact defined as zero.
If you attempt to dereference a null pointer you will get a fault.
What's the problem with using NULL? That's the general way this is handled. If you really need to distinguish between "caller passed nothing" and "caller passed NULL", then use 0xFFFFFFFF on a 32-bit system or 0xFFFFFFFFFFFFFFFF on a 64-bit system.
point * funct(point * p = (point *)(-1))
{
if (p == (point *)(-1))
{
p = new point();
}
if (p == NULL)
{
// special case handling
return NULL;
}
// fill in p
return p
}
The '-1' cast will always be the maximum pointer value as long as you are on a two's-compliment architecture. Feel free to substitute the C-style cast with a reinterpret cast if you prefer.
You should pass it NULL (have null be default...) if you want to allocate, and pass an empty pointer if you want to fill in.
As jeffamaphone commented, there is a difference between an empty pointer and NULL, use your conditional statements to check if it is an empty pointer or NULL
However you can choose not to pass a parameter and it will return a dynamically allocated pointer but if you do pass a pointer then it just fills it in instead of creating one on the heap. This is a single function not overloaded.
Instead of using default arguments, you could overload the function:
point* funct(point *p = some_value)
{
// fills p
}
point* funct()
{
return funct(new point());
}
It might not be the right way but somewhere I think in the linux libraries there was a function that works exactly like above not sure how it is allocated internally though
I'm not aware of any such function. I would guess you're thinking of realloc which takes a pointer and a size_t and then decides whether to allocate memory, adjust already allocated memory, or free memory.
Now i can't think if this is right way to do it and if it is then what could be a good some_value? it can't be NULL because when you pass empty pointer it will also be NULL and not sure if it is safe to have it greater than 0. Also you can't have negative numbers on pointers either, so whats a good safe value?
I think your confusion comes from a fundamental misunderstanding of the NULL pointer.
Observe:
int x = 5;
int* px = &x;
int* p_null = NULL;
int* p;
int* p_new = new int();
px points to x, so it's not NULL. p_null begins life as NULL which means it doesn't point to anything.
I think you're using the term "empty pointer" to refer to something like p or p_new. However, although p doesn't point to a valid object it wasn't set to NULL either. It's effectively an invalid pointer, and there is no portable way to tell that it's invalid (on some machines it may be possible to tell if something is obviously not valid, but even then it's not possible to catch all invalid pointers -- see note -- and you probably don't want to anyway -- second half).
And p_new points to a valid address in dynamic memory. It's not NULL. It's not empty. In fact, new will initialize the int to 0.
In other words, NULL is the value you pass to functions that expect a pointer to tell them you don't have a pointer. That's what it is. And there isn't really the idea of an empty pointer. Dangling pointers (either uninitialized pointers, or pointers to memory that you don't have access to) aren't NULL, because if they were NULL they wouldn't dangle. And it's impossible to validate pointers in all cases to determine if they are valid.
NOTE
Consider:
int* p_new2 = new int();
delete p_new2;
delete does not set p_new2 to NULL. So after the delete, p_new2 will have an address in the correct range for a valid pointer (meaning that Windows' VirtualQuery method will say "sure, a pointer could point there"), but will not have permission to actually dereference that memory address.
NOTE 2
This is a terribly bad idea, don't do it:
int* funct()
{
int y = 5;
return &y;
}
int* x = funct();
y ceases to exist after funct() returns. So the the pointer to y that funct() hands you points to something that doesn't exist. So you get a dangling pointer. You're not talking about doing this, but it's a common mistake, and it will bite you.
Default value is what it is — default value. There's no such thing like not passing value here. It may only happen with variable parameters count, but that's different story.
And what is an "empty pointer"?
Are you looking for this:
point* funct(point *p = some_value)
{
if (p == NULL)
return NULL;
if (p == some_value)
p = new point;
return p;
}
Okay I've decided not to use that idiom seems bad although I know one of the unix or linux system libraries had a function like that.
I'm not answering my own question but I just remembered the ctime idiom which is probably a much safer way to do what I want. I'm talking about the time() function.
Where it takes a pointer or returns a object by value.
I think it probably even gives better flexibility of returning by value, heap or stack allocation with pointer thats user controlled. I don't know why I didn't think of this before.
What do you guys thing, the ctime idiom is much better right?
Edit: Does that idiom use NULL check?
If you really wish to split them in such a way you can't accidentally provide the default function, you ought ot overload the functions.
point* funct() {
//alocate a point* p here
return funct(p);
}
and
point* funct(point *p) {
//do stuff
}