Assign value to member of struct using double pointer - c++

I have a function that takes a double pointer to a struct and assigns a value. However I get an "access violation writing location ..." when trying to access the member member1.
This is my code:
struct mystruct{
unsigned int member1;
void * data;
};
int main(){
mystruct **foo = new mystruct *;
bar(foo);
}
void bar(unsigned int val, mystruct ** foo)
{
(*foo)->member1 = val;
}

You just created a new mystruct pointer. That means:
You get allocated a memory block, large enough to hold a address, and assign it to the pointer which is pointing to a pointer that points to a mystruct member.
That doesn't mean, that there is a valid address hold in the pointer which you expect to be pointing to a mystruct element. Even more currently there isn't even a valid address, where the pointer to the pointer is pointing on, as you just assigned a valid memory area to it, what doesn't mean there is a usefull address stored in.
So at all, what you want is:
You want a pointer which has a valid memory block to store a address in of another pointer, which is pointing to a valid memory area, where is a (probably valid) mystruct stored in.
What you are doing is: you are requesting a memory area where you COULD (what you aren't even doing) store a poitner to another pointer... and so on.
so what you should do is:
mystruct **foo = new mystruct *;
*foo = new mystruct;

I have a function that takes a double pointer
That's weird. If you can, simplify it to take a reference:
void bar(unsigned int val, mystruct & foo) {
foo.member1 = val;
}
mystruct foo;
bar(42, foo);
If you don't have control over the function, then you'll need an object at the end of the pointer trail:
mystruct foo;
mystruct * pointless = &foo;
bar(42, &pointless);
You can, of course, mess around with new if you really want to; but that's almost certainly a bad idea.
Your code allocates and leaks a pointer, but doesn't initialise it to point to a valid object; so dereferencing it gives undefined behaviour.

This C-style function:
void bar1(mystruct* foo) {
foo->member1 = val;
}
takes an argument of type mystruct* in order for changes made to object that foo points to to be visible to the caller. However this function:
void bar(unsigned int val, mystruct ** foo) {
(*foo)->member1 = val;
}
takes pointer to mystruct* (most likely) in order to to modify the pointer itself, i.e. in order for changes made to the pointer to be visible to the caller and thus probably meant to be used this way:
mystruct* foo = new mystruct;
bar(&foo);
... yet usually it is reasonable to avoid dynamic allocation and passing pointers should be rather rarity than a common practice. Prefer objects with automatic storage duration over the dynamically allocated ones and prefer passing by reference over passing by pointer (when possible).

The other answers are good advice. But also, if you have control over the bar function, and need to be able to change in bar to what object your mystruct * pointer points to (which is probably the reason why you have a double pointer in the first place), then the cleanest approach is to use the following signature for bar:
void bar(unsigned int val, mystruct * &foo);
It passes by reference a pointer, so you are able to change to what object the pointer points to, without sacrificing readability of the code, for instance:
int main()
{
mystruct * foo = new mystruct;
bar(42, foo);
}
void bar(unsigned int val, mystruct * &foo)
{
foo->member1 = val;
foo = new mystruct;
}
A complete usage scenario without memory leak could be:
int main()
{
// allocate dynamically a mystruct whose member1 is equal to 1.
mystruct * foo1 = new mystruct;
mystruct * foo2 = foo1;
foo1->member1 = 1;
// pass by reference foo1
bar(42, foo1);
// here, foo1->member1 == 42 and foo2->member1 == 10
// free memory
delete foo1; // the one allocated in bar()
delete foo2; // the one allocated in main()
}
void bar(unsigned int val, mystruct * &foo)
{
// modify the object allocated in main()
foo->member1 = 10;
// allocate dynamically a mystruct, store its address in foo
foo = new mystruct;
foo->member1 = val;
}

Related

why when a function takes a pointer, then we pass the address of a specific variable, and not a pointer?

for example :
void foo(int *ptr) {
some code///
}
int main() {
int x = 5;
foo(&x);
}
but not this :
void foo(int *ptr) {
some code///
}
int main() {
int x = 5;
int *ptr = &x
foo(ptr);
}
I read articles about this, but everything that says there is that "we are passing the address", but not a pointer, I can not understand why, please tell me
The following snippet is fine(legal/valid) because variable ptr is a pointer meaning it holds the address of an int(in this case). And this is exactly what foo expects as the type of its parameter.
void foo(int *ptr) {
// some code///
}
int main() {
int x = 5;
int *ptr = &x;//ptr is a pointer to an int
foo(ptr);//this works because foo expects a pointer to an int
}
Your example (after the modification)
int *ptr = &x
foo(ptr);
is perfectly valid and does exactly the same as foo(&x). The only difference is that you declare an extra variable of type int*. The compiler will typically optimize it away, so there's no real difference between the two.
A pointer holds the memory address of a variable. If a function takes a pointer, you are actually passing the address of the variable that it is pointing to so passing a pointer is actually passing an address. Both cases are legal and do the same thing.

Unable to allocate memory with new[] from within templated function

I am trying to create a function that allocates memory. It allocates it, but the problem is that it only appears to do so inside the function, but after it returns the memory allocated is no longer there. Almost as if I am allocating memory with another pointer, but there should be no other there.
template<class T> struct rmv_ptr { using type = T; };
template<class T> struct rmv_ptr<T*> { using type = T; };
template<class T> struct rmv_ptr<const T*> { using type = T; };
template<class T> bool alloc(T inst, int size)
{
return (nullptr != (inst = new typename rmv_ptr<T>::type[size]));
}
Say I call it like this:
wchar_t* a;
alloc(a, 10);
inst will be wchar_t*, so a's pointer should point to the allocate memory, no?
When you pass an integer to a function, you cannot change the integer.
When you pass a pointer to a function, you cannot change the pointer.
When you pass a pointer to a function, you can change the pointed-to value.
Pass-by-non-const-reference is the exception; it allows you to change the passed value. Passing a pointer by reference therefore allows you to change the pointer.
On an unrelated note, the base rule for "remove pointer" template logic won't work. The problem is that you have two uses of T. There's the argument T& inst, which has to match T* returned by new. I.e. if T is int, then rmv_ptr<int>::type is int, and new will return an int*. But you can't assign that int* to int& inst.
Pointers are no different from non-pointers as modifications are not visible outside when passed by value to a function:
void foo(int* p) { p = 0; } // only modifies the local p
void foo(int a) { a = 0; } // only modifies the local a
However, pointers allow you to modify what the pointer does point to and that can be observed by the caller:
// assume p points to an int
void bar(int* p) { *p = 42; }
This will not modify p itself. When called via
int x;
int xp = &x;
bar(xp);
then p inside bar is a copy of xp, though they both point to the same int.
But when you call new, then new returns you a pointer to the allocated memory, so you need to change the pointers value, not just the pointee. Either pass it by reference, or return the pointer from the function (making it a parameter is of no use anyhow).

Alternative to Placement New that does not override placement memory location

I am using polymorphism with virtual functions and need to define a pointer as a child object type before using it. For example:
struct object {
virtual void function() {}
};
struct object_child : object {
int a;
int b;
void function() {std::cout<<"working";}
};
int main() {
uint64_t sandbox[512];
object * o1 = new ((void *) &sandbox[0]) object_child();
o1->function();
}
This works fine except that the memory at the location is overwritten. Is there a cast or some operator I can use that would result in the same o1 without overwriting the memory location?
*** EDIT - SK - Adding cout to function -
You say the bytes at 0x20000 match the data structure layout of object_child, but it actually doesn't. Namely, you're overlooking that an object_child has an invisible member you're not accounting for - the virtual function pointer. Which means no pointer cast will work, period. You'll have to create an actual object_child object with it's own copy of that state.

C++ pointer and address clarification in relation to the current object

So far to my understanding, when defining a pointer variable, we are allocating space in RAM for that variable.
int *p;
Would define a space in RAM. Then we assign a memory address to that pointer using `&variable'.
I'm looking over at an example on: *this vs this in C++
The code is:
#include <iostream>
class Foo
{
public:
Foo()
{
this->value = 0;
}
Foo get_copy()
{
return *this;
}
Foo& get_copy_as_reference()
{
return *this;
}
Foo* get_pointer()
{
return this;
}
void increment()
{
this->value++;
}
void print_value()
{
std::cout << this->value << std::endl;
}
private:
int value;
};
int main()
{
Foo foo;
foo.increment();
foo.print_value();
foo.get_copy().increment();
foo.print_value();
foo.get_copy_as_reference().increment();
foo.print_value();
foo.get_pointer()->increment();
foo.print_value();
return 0;
}
I don't understand what the purpose of putting the * operator in front Foo* get_copy() and Foo* get_pointer() does. Why do I get an error if I removed the * from the Foo* functions while returning this not *this?
edit:
Also, why is:
foo.get_copy().increment();
foo.print_value();
yielding 1 not 2?
I don't understand what the purpose of putting the * operator in front Foo* get_copy() and Foo* get_pointer() does
Foo* get_pointer()
Foo* is a pointer that points to Foo object.
this is also a pointer that implicitly bind to the calling object of the member function. That's why the return type of those functions are Foo* not Foo.
The * is part of the type. So int means type int, and
int* type pointer to int. If the function returns pointer
to int, it is int* foo(), and if it retu rns a pointer to
Foo, it is Foo* Foo::get_pointer().
The definition reserves space for the defined object. A
declaration doesn't reserve any space, and definitions of things
that aren't objects (e.g. references or functions) don't reserve
any space either, at least not that you can see. (Obviously, a
function does exist somewhere in memory, and in many cases, the
compiler will need space as well for its implementation of a
reference. But they are invisible within the scope of C++.)
this, is always a pointer in C++, though you don't mention it explicitly anywhere. So while returning a this pointer, should use Foo*
this is actually an implicit object passed during function call, which is a pointer to the object which calls the function
It seems that you have changed the code from the example that you refer to so that get_copy() no longer returns a copy.
There are 2 ways of using * in your code example. One is for type declaration and the other is the dereferencing operator.
First the type declarations:
int *p means declaring p as a variable of type "pointer to an int".
Foo *get_pointer() means that the function get_pointer will return a value of type "pointer to a Foo object".
Now the dereferencing:
*p means "the value that p points to".
int a = 42;
int *p; // p is of type "pointer to an int"
p = &a; // set p to the address of a (p now "points to" a)
a = 117; // change the value of a
int x = *p; // set x to the value that p points to (which is a) - x will be 117
this is just a pointer to the object. *this means "the object that this points to". In your example this is of type Foo* (pointer to a Foo object) while *this is of type Foo (a Foo object).
"this" is a pointer.
you want to return a pointer to the instance (a specific allocated object).
Foo* get_pointer(){
return this;
}
or you want to return a pointer to the copy, allocate a new object.
//need to implement the copy here
Foo* get_copy(){
return this;
}
and not to the reference (address of the instance). this is why you need to return the pointer.

Return class pointer from a function

I am not sure what is wrong with this (keep in mind I'm kinda sorta new to C++)
I have this class:
Foo
{
string name;
public:
SetName(string);
}
string Foo::SetName(string name)
{
this->name = name;
return this->name;
};
//////////////////////////////////////////////
//This is where I am trying to return a Foo pointer from this global function:
Foo * ReturnFooPointer()
{
Foo foo;
Foo * foo_ptr;
foo_ptr = &foo;
return foo_ptr;
}
At compile time, this compiles just fine. However at run time it throws a runtime exception(Some sort of access violation)
What am I doing wrong?
You need to use the new keyword instead to create new Foo on the heap.
The object on the stack will be freed when the function ends, so you are returning a pointer to an invalid place in memory.
Here is the correct code.
Foo * ReturnFooPointer()
{
Foo * foo_ptr = new Foo();
return foo_ptr;
}
Remember later to delete the pointer you are returning.
So later in code:
Foo *pFoo = ReturnFooPointer();
//Use pFoo
//...
delete pFoo;
You're returning a pointer to a local object on the stack. It goes out of scope the moment your function returns, and is invalid.
You should create a new instance to return, i.e.,
Foo* foo_ptr = new Foo();
This will create an object in the heap and will live until you call delete on it.
the actual object is allocated on the stack so it is destroyed when it goes out of scope (when the function returns). If you allocate it on the heap (with new), it will be alive until you delete it