I have a method with the prototype:
bool getAssignment(const Query& query, Assignment *&result);
I am a bit confused about the type of the second param (Assignment *&result) since I don't think I have seen something like that before. It is used like:
Assignment *a;
if (!getAssignment(query, a))
return false;
Is it a reference to a pointer or the other way around ? or neither ? Any explanation is appreciated. Thanks.
It's a reference to a pointer. The idea is to be able to change the pointer. It's like any other type.
Detailed explanation and example:
void f( char* p )
{
p = new char[ 100 ];
}
int main()
{
char* p_main = NULL;
f( p_main );
return 0;
}
will not change p_main to point to the allocated char array (it's a definite memory leak). This is because you copy the pointer, it's passed by value (it's like passing an int by value; for example void f( int x ) != void f( int& x ) ) .
So, if you change f:
void f( char*& p )
now, this will pass p_main by reference and will change it. Thus, this is not a memory leak and after the execution of f, p_main will correctly point to the allocated memory.
P.S. The same can be done, by using double pointer (as, for example, C does not have references):
void f( char** p )
{
*p = new char[ 100 ];
}
int main()
{
char* p_main = NULL;
f( &p_main );
return 0;
}
For something like this, you basically read the declaration from right to left (or inside out).
In other words, you want to start from the name of the item being declared, then progress outward. In this case, progressing directly from the name to the type, we get:
Related
Under what circumstances might you want to use multiple indirection (that is, a chain of pointers as in Foo **) in C++?
Most common usage as #aku pointed out is to allow a change to a pointer parameter to be visible after the function returns.
#include <iostream>
using namespace std;
struct Foo {
int a;
};
void CreateFoo(Foo** p) {
*p = new Foo();
(*p)->a = 12;
}
int main(int argc, char* argv[])
{
Foo* p = NULL;
CreateFoo(&p);
cout << p->a << endl;
delete p;
return 0;
}
This will print
12
But there are several other useful usages as in the following example to iterate an array of strings and print them to the standard output.
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
const char* words[] = { "first", "second", NULL };
for (const char** p = words; *p != NULL; ++p) {
cout << *p << endl;
}
return 0;
}
IMO most common usage is to pass reference to pointer variable
void test(int ** var)
{
...
}
int *foo = ...
test(&foo);
You can create multidimensional jagged array using double pointers:
int ** array = new *int[2];
array[0] = new int[2];
array[1] = new int[3];
One common scenario is where you need to pass a null pointer to a function, and have it initialized within that function, and used outside the function. Without multplie indirection, the calling function would never have access to the initialized object.
Consider the following function:
initialize(foo* my_foo)
{
my_foo = new Foo();
}
Any function that calls 'initialize(foo*)' will not have access to the initialized instance of Foo, beacuse the pointer that's passed to this function is a copy. (The pointer is just an integer after all, and integers are passed by value.)
However, if the function was defined like this:
initialize(foo** my_foo)
{
*my_foo = new Foo();
}
...and it was called like this...
Foo* my_foo;
initialize(&my_foo);
...then the caller would have access to the initialized instance, via 'my_foo' - because it's the address of the pointer that was passed to 'initialize'.
Of course, in my simplified example, the 'initialize' function could simply return the newly created instance via the return keyword, but that does not always suit - maybe the function needs to return something else.
If you pass a pointer in as output parameter, you might want to pass it as Foo** and set its value as *ppFoo = pSomeOtherFoo.
And from the algorithms-and-data-structures department, you can use that double indirection to update pointers, which can be faster than for instance swapping actual objects.
A simple example would be using int** foo_mat as a 2d array of integers.
Or you may also use pointers to pointers - lets say that you have a pointer void* foo and you have 2 different objects that have a reference to it with the following members: void** foo_pointer1 and void** foo_pointer2, by having a pointer to a pointer you can actually check whether *foo_pointer1 == NULL which indicates that foo is NULL. You wouldn't be able to check whether foo is NULL if foo_pointer1 was a regular pointer.
I hope that my explanation wasn't too messy :)
Carl: Your example should be:
*p = x;
(You have two stars.) :-)
In C, the idiom is absolutely required. Consider the problem in which you want a function to add a string (pure C, so a char *) to an array of pointers to char *. The function prototype requires three levels of indirection:
int AddStringToList(unsigned int *count_ptr, char ***list_ptr, const char *string_to_add);
We call it as follows:
unsigned int the_count = 0;
char **the_list = NULL;
AddStringToList(&the_count, &the_list, "The string I'm adding");
In C++ we have the option of using references instead, which would yield a different signature. But we still need the two levels of indirection you asked about in your original question:
int AddStringToList(unsigned int &count_ptr, char **&list_ptr, const char *string_to_add);
Usually when you pass a pointer to a function as a return value:
ErrorCode AllocateObject (void **object);
where the function returns a success/failure error code and fills in the object parameter with a pointer to the new object:
*object = new Object;
This is used a lot in COM programming in Win32.
This is more of a C thing to do, in C++ you can often wrap this type of system into a class to make the code more readable.
So I'm looking for clarification on something that works. I'm pretty sure I understand what is happening but wanted to be sure before proceeding with my work.
I have a function defined as follows:
name* createName(char* firstName, char* lastName)
{
name* newName = (name*)malloc(sizeof(name));
initStringValue(&newName->firstName, firstName);
initStringValue(&newName->lastName, lastName);
newName->firstNameSize = strlen(newName->firstName);
newName->lastNameSize = strlen(newName->lastName);
return newName;
}
The structure "name" is defined like so:
struct name
{
char* firstName;
char* lastName;
int firstNameSize;
int lastNameSize;
};
Another function responsible for the copy of the name strings is written like the following:
void initStringValue(char** destination, char* source)
{
int length = strlen(source) + 1;
int size = length * sizeof(char);
*destination = (char*)malloc(size);
memset(*destination, 0, size);
strcpy(*destination, source);
}
If I'm understanding what I've done here, by using the & operator I've signified that I wish to send not a value but its associated memory address. In a statement such as
&newName->firstName
where the struct member firstName is a char* I've indicated that I would like to send the memory address of this pointer and not the pointers value (which happens to be a memory address in and of itself). The -> operator dereferences this pointer to the member of the pointer but then the & operator essentially returns us to the firstName memory reference instead, allowing me to manipulate information at that memory reference.
Now things get wild (for me anyway). To actually work with that memory reference, I end up using double indirection (so very passive aggressive). As it follows a memory reference (like that of &newName->firstName) sent to a char** like that of char** destination in the initStringValue function, would be a pointer of a pointer where the latter is assigned the memory reference returned by &newName->firstName. By then using *destination I'm working with a pointer pointed to the memory reference of &newName->firstName. Or stated differently, a pointer whose first and only member is the memory reference of newName->firstName.
Am I actually understanding this correctly?
Am I actually understanding this correctly?
After reading your description, I'll say yes
I'll try to explain it with some examples.
If you do this:
void foo(int a)
{
a = 5;
}
int main()
{
int a = 10;
foo(a);
printf("%d\n", a);
return 0;
}
You'll get the output: 10
That's because the function parameters are local variables to the function. In other words - any change made to a function parameter is lost when the function returns, i.e. the variable in main will not be changed.
If you want a function to change the value of a variable in main (aka in the caller), you'll have to pass a pointer. Like:
void foo(int* a) // notice int*
{
*a = 5; // notice *a
}
int main()
{
int a = 10;
foo(&a); // notice &a
printf("%d\n", a);
return 0;
}
This will output: 5
This is a general rule regardless of the type. I used int in the example but it applies to any type - pointers as well.
So let's take an example with a pointer:
void foo(char** a, int size) // notice char**
{
*a = malloc(32); // malloc memory
strcpy(*a, "Hello world"); // copy some data into the memory
}
int main()
{
char* a = NULL; // a is not pointing to anything yet
foo(&a);
// Now a points to the malloc'ed memory
printf("%s\n", a);
return 0;
}
This will output: Hello world
So I've been working on memory management and have a particular issue when it comes to moving objects that contain function objects that wrap lambda's that capture data. Suppose the following example:
typedef std::function < void( int ) > funcType;
class Something
{
private:
int _myNum = 0;
public:
funcType GetSetIt( )
{
return [&] ( int a )
{
_myNum = a;
};
}
void SeeIt( )
{
std::cout << _myNum << std::endl;
}
int GetIt( )
{
return _myNum;
}
};
And the following operations:
auto destination = ( Something* ) malloc( sizeof( Something ) );
auto alt = ( funcType* ) malloc( sizeof( funcType ) );
auto size = sizeof( funcType );
auto s = new Something( );
auto setIt = s->GetSetIt( );
setIt( 10 );
s->SeeIt( );
auto a = s->GetIt( );
memcpy( destination, s, sizeof( Something ) );
memset(s, 0, sizeof( Something ) );
memcpy( alt, &setIt, sizeof( funcType ) );
memset( &setIt, 0, sizeof( funcType ) ); // point 1
(*alt)( 15 );
destination->SeeIt( );
auto b = destination->GetIt( );
A quick explanation:
Create a new Something and call all of it's members to make sure it's working correctly. Then move it to a new location and delete/clear where it used to exist. Also move the function object to a new location and clean up after. Then, using pointer's to the new locations, call the function object and the methods on the object.
The first issue is that everything is moving along smoothly until I memset the original location of the function object. If you comment out that line (noted with // point 1) you'll notice it does not crash.
This is a little strange to me, but I don't fully understand how function objects are laid out in memory and was hoping for a little light to be shed in that area. I would assume that if I block-copied the entire object to another area and cleared the old space (not deleting it because it's on the stack) that it and all of it's references would be preserved.
The second issue, assuming you've commented out the memset line is that "expected results" are not the same as "desired results". I expect that calling alt will set _myNum on s to 15, and it does. But I want to update alt's pointer to Something (which I usually refer to as it's this pointer) to point to destination. How can I achieve that? Can it be done dependably across compilers? I've been worried that, although I could conceivably find where it's stored and update the value, the solution won't be solid because lambda's can be implemented in a variety of ways across compilers and there may be some "magic" at hand.
Any help or insight into these issues is greatly appreciated. If I'm not clear on what's going on, comment and I'll provide more detail where needed. Thanks in advance!
function is not trivially copyable (3.9p9, 9p6) so you cannot copy it with memcpy. Use the is_trivially_copyable trait to detect whether a type is trivially copyable.
If you want to "move" an object of a non-trivially copyable type from one location to another, use placement new with its move constructor and perform a destructor call on the previous location:
new (*buf) T(std::move(obj));
obj.~T();
You should use placement new and ensure the setter is taken from the copied object:
#include <functional>
#include <iostream>
// ...
int main() {
char source[sizeof(Something)];
char source_setter[sizeof(funcType)];
Something* src = new (source) Something;
// Get the setter from the source object.
funcType* src_setter = new (source_setter) funcType(src->GetSetIt());
(*src_setter)(0);
char destination[sizeof(Something)];
char destination_setter[sizeof(funcType)];
Something* dst = new (destination) Something(*src);
// Get the setter from the destination object.
funcType* dst_setter = new (destination_setter) funcType(dst->GetSetIt());
(*dst_setter)(1);
src->SeeIt();
dst->SeeIt();
src_setter->~funcType();
src->~Something();
dst_setter->~funcType();
dst->~Something();
}
void process( int boat ) { ; }
const void(*sequence_A[])( int ) = { process, process }; //ERROR
const void(**func_sequence)( int ) = sequence_A;
(*func_sequence++)( 7 );
Why won't this compile? I want const to refer to the array, not the contents of the array.
Error 1 error C2440: 'initializing' : cannot convert from 'void (__cdecl *)(int)' to 'const void (__cdecl *)(int)'
EDIT: So you guys are saying it doesn't exist. Fair enough. Just to be clear, I'm posting this analogy of the functionality I wanted but this is with int instead of function ptrs
//Compiles without error
int number1 = 7;
int number2 = 3;
const int* sequence_B[] = { &number1, &number2 };
const int** numbers = sequence_B;
int check = **numbers++; //value is 7
int chec2 = **numbers++; //value is 3
Okay, let's analyze the meaning of your statement
const void(*sequence_A[])( int ) = { process, process }; //ERROR
The way I remember the parsing of *x[] is that the second argument of main is char* argv[], so, it's an array of pointers. In other words, sequence_A is to be indexed, and then the result is to be dereferenced.
Then, to that you can apply a function call argument parenthesis with an int value, and as a result you should get a …
const void ?
Well that's not entirely meaningful. You can have a pointer to const void, but you can't dereference that pointer: you can't "get at" the const void directly. Yet here is some pointer to a function that produces as its expression value a const void.
To match that you would need
const void process( int boat ) { ; }
and although I haven't tried it, I doubt that any compiler will accept it. [Update: as it turns out, at least g++ accepts it, so it is one solution. But it's a very unconventional function signature. And not at all what you're after!]
In short, remove that const.
On a related note, as mentioned already in a comment you can't have a const raw array, except in the sense of a raw array of const items.
It's a corner case of the language, a problematic type system aberration inherited from C.
Along with the array type decay to pointer, also problematic.
Addendum: example of how to make the array items const:
void process( int boat ) { ; }
int main()
{
void(* const sequence_A[])( int ) = { process, process }; // OK
//sequence_A[0] = process; //ERROR
}
Suppose I have a class:
class test {
public:
void print();
private:
int x;
};
void test::print()
{
cout<< this->x;
}
and I have these variable definitions:
test object1;
test object2;
When I call object1.print() this happens to store address of object1 and so I get x from object1 printed and when I call object2.print() this happens to store address of object2 and I get x from object2 printed. How does it happen?
Each non-static member function has an implicit hidden "current object" parameter that is exposed to you as this pointer.
So you can think that for
test::print();
there's some
test_print( test* this );
global function and so when you write
objectX.print();
in your code the compiler inserts a call to
test_print(&objectX);
and this way the member function knows the address of "the current" object.
You can think of the this pointer being an implicit argument to the functions. Imagine a little class like
class C {
public:
C( int x ) : m_x( x ) { }
void increment( int value ) {
m_x += value; // same as 'this->m_x += value'
}
int multiply( int times ) const {
return m_x * times; // same as 'return this->m_x * times;'
}
private:
int m_x;
};
which allows you to write code like
C two( 2 );
two.increment( 2 );
int result = two.multiply( 3 );
Now, what's actually happening is that the member functions increment and multiply are called with an extra pointer argument, pointing to the object on which the function is invoked. This pointer is known as this inside the method. The type of the this pointer is different, depending on whether the method is const (as multiply is) or not (as is the case with increment).
You can do something like it yourself as well, consider:
class C {
public:
C( int x ) : m_x( x ) { }
void increment( C * const that, int value ) {
that->m_x += value;
}
int multiply( C const * const that, int times ) const {
return that->m_x * times;
}
private:
int m_x;
};
you could write code like
C two( 2 );
two.increment( &two, 2 );
int result = two.multiply( &two, 3 );
Notice that the type of the this pointer is C const * const for the multiply function, so both the pointer itself is const but also the object being pointed to! This is why you cannot change member variables inside a const method - the this pointer has a type which forbids it. This could be resolved using the mutable keyword (I don't want to get side-tracked too far, so I'll rather not explain how that works) but even using a const_cast:
int C::multiply( int times ) const {
C * const that = const_cast<C * const>( this );
that->m_x = 0; // evil! Can modify member variable because const'ness was casted away
// ..
}
I'm mentioning this since it demonstrates that this isn't as special a pointer as it may seem, and this particular hack is often a better solution than making a member variable mutable since this hack is local to one function whereas mutable makes the variable mutable for all const methods of the class.
The way to think about it is that this is simply a pointer to the memory for whichever object you're currently working with. So if you do obj1.print(), then this = &obj1;. If you do obj2.print(), then this = &obj2;.
this has different values for different objects
Each instance of class test gets it's own copy of member variable x. Since x is unique for each instance, the value can be anything you want it to be.
The variable this, refers to the instance to which it is associated. You don't have to use the variable 'this'. You could just write:
void test::print()
{
cout << x;
}