Use of * and & together in function signature - c++

I was playing through c++ and trying to understand vector and its signature .
In below method printPrimes I need to use pointer with address of why ?
Is vector<int> &primes not enough as from main method printPrimes is already sending address .
void printPrimes(long long l, long long r, vector<int>* &primes) {
// some code
}
vector<int>* sieve() {
vector<int> *prime = new vector<int>();
return prime;
}
int main() {
vector<int> *primes = sieve();
printPrimes(l, r, primes);
return 0;
}

I need to use pointer with address of
Here, & does not mean "address of"; it means the type "reference to".
It's clearer if you write it not like this:
vector<int>* &primes
but like this:
vector<int>*& primes
Though the choice of whitespace is artificial, that better documents that this & is "part of the type".
Have some types:
std::vector<T> = A vector of Ts
std::vector<T>& = A reference to a vector of Ts
std::vector<T>* = A pointer to a vector of Ts
std::vector<T>*& = A reference to a pointer to a vector of Ts
std::vector<T>*** = A pointer to a pointer to a pointer to a vector of Ts
std::vector<T>**& = A reference to a pointer to a pointer to a vector of Ts
…and so forth.
As for why you need a vector<int>*& for printPrimes to do its job, we could not tell you without actually being able to see it. I will say that it seems unlikely it needs a pointer at all, and that if it wants to modify that pointer it's going to cause problems with the new and delete in the calling scope.
In fact, all that dynamic allocation is completely pointless and only complicates things.
The following was likely intended instead:
void printPrimes(long long l, long long r, vector<int>& primes) {
// some code
}
vector<int> sieve() {
vector<int> prime;
return prime;
}
int main() {
vector<int> primes = sieve();
printPrimes(l, r, primes);
}

vector<int>* &primes parameter has to be read this way:
Reference to a pointer of vector of int
and not
Address of a pointer of vector of int (which, you are right, would be useless)
Passing by reference allows to directly manipulate any instance outside of scope (like with pointers, but a safer way since a reference cannot be nullptr, and its existence is auto-managed (no need to delete)).

In c++ & in function parameter used to pass parameter by reference. vector<int>* &primes declares primes to be a reference to a pointer to vector<int>.
If printPrimes means to print only the vector passed to the function then the signature
void printPrimes(long long l, long long r, vector<int> &primes);
can also do the job.
Reference to a pointer is needed when the pointer passed to the function is need to be modified and it's effect is expected to seen in the caller function.
void foo(int*& p){
p = new int[10];
// rest of the code
}
if a function bar is calling foo like
void bar(/* some parameters */){
// ...
int *p;
foo(p);
// rest of the code
}
foo is modifying the pointer itself and this modification will be seen to bar also and memory allocated to p can be accessed from bar.

Related

Is it possible to typedef array of function pointer in c++? [duplicate]

Arrays of function pointers can be created like so:
typedef void(*FunctionPointer)();
FunctionPointer functionPointers[] = {/* Stuff here */};
What is the syntax for creating a function pointer array without using the typedef?
arr //arr
arr [] //is an array (so index it)
* arr [] //of pointers (so dereference them)
(* arr [])() //to functions taking nothing (so call them with ())
void (* arr [])() //returning void
so your answer is
void (* arr [])() = {};
But naturally, this is a bad practice, just use typedefs :)
Extra:
Wonder how to declare an array of 3 pointers to functions taking int and returning a pointer to an array of 4 pointers to functions taking double and returning char? (how cool is that, huh? :))
arr //arr
arr [3] //is an array of 3 (index it)
* arr [3] //pointers
(* arr [3])(int) //to functions taking int (call it) and
*(* arr [3])(int) //returning a pointer (dereference it)
(*(* arr [3])(int))[4] //to an array of 4
*(*(* arr [3])(int))[4] //pointers
(*(*(* arr [3])(int))[4])(double) //to functions taking double and
char (*(*(* arr [3])(int))[4])(double) //returning char
:))
Remember "delcaration mimics use". So to use said array you'd say
(*FunctionPointers[0])();
Correct? Therefore to declare it, you use the same:
void (*FunctionPointers[])() = { ... };
Use this:
void (*FunctionPointers[])() = { };
Works like everything else, you place [] after the name.
I've been building a game engine and have found that I needed dynamically allocated arrays of function pointers.
To address this simply, I've opted for encapsulating the function pointers inside a class.
Here's a simple example:
class Function{
private:
public:
int (*sampleFunction)(int);
};
static int returnInt(int val){
int ret = 20 * i;
return ret;
}
int main(void){
Function *functions; /* V put yours here V */
size_t functionCount = getFunctionCount();
functions = new Function[functionCount];
for(int i=0; i<functionCount; i++)
functions[i].sampleFunction = &returnInt;
for(int i=0; i<functionCount; i++)
functions[i].sampleFunction(i);
return 0;
}
Where can this be useful?
Say that you have a graphical application that you're building that creates buttons out of an undefined number of files in a directory.
Each button has a unique "hitbox" coordinate relative to it's position in an array, and you need to be able to uniquely handle a mouse click for each button.
The Functions class is meant to be placed inside another, more complex, class. Where the point of the function pointer is to make it easier to redefine the button click event when different algorithms are required for the same "form element".

Array passing and returning

I was wondering.. Whenever I deal with arrays, when I have to cut it, or sort it, or anything, and then return it, I pass it to the void function like f(array, length, newarray) and in the function declaration I have void f(T *array, int length, T *&new array).
Is there a better way to do this?
Here's some code, I want to remove repeats from an array:
template<class T>
void eliminate(T *niz, int duzina, T *&podniz)
{
int ind;
podniz = new T[duzina];
for (int i = 0; i<duzina; i++)
{
ind = 0;
for (int j = i; j<duzina; j++)
{
if (niz[i] == niz[j])ind++;
}
if (ind == 1)podniz[nova++] = niz[i];
}
}
As already noted in the comments, you really want std::vector.
The main problem with your code is that there is no way to tell how many of the output elements are actually initialized. And accessing uninitialized elements is Undefined Behavior, so you are returning a time bomb to the caller.
With std::vector<T> eliminate(std::vector const&), there's no such doubt. The returned vector has exactly .size() elements.
Vector is also exception-safe. Your code will leak memory if the copy constructor of T throws, e.g. on a std::bad_alloc.
Sure. You can use pointers and pass the array by reference to the function.
Then manipulate the array and return from the function with void type i.e no need of returning the array as it is passed by reference.

Getting results from functions with 'void' return type, while resulting variable is one of the input arguments - C++

I got this library of mathematical routines ( without documentation ) to work on some task at college. The problem I have with it is that all of its functions have void return type, although these functions call one another, or are part of another, and the results of their computations are needed.
This is a piece of ( simplified ) code extracted from the libraries. Don't bother about the mathematics in code, it is not significant. Just passing arguments and returning results is what puzzles me ( as described after code ) :
// first function
void vector_math // get the (output) vector we need
(
double inputV[3], // input vector
double outputV[3] // output vector
)
{
// some variable declarations and simple arithmetics
// .....
//
transposeM(matrix1, matrix2, 3, 3 ); // matrix2 is the result
matrixXvector( matrix2, inputV, outputV) // here you get the result, outputV
}
////////
// second function
void transposeM // transposes a matrix
(
std::vector< std::vector<double> > mat1, // input matrix
std::vector< std::vector<double> > &mat2, // transposed matrix
int mat1rows, int mat1columns
)
{
int row,col;
mat2.resize(mat1columns); // rows
for (std::vector< std::vector<double> >::iterator it=mat2.begin(); it !=mat2.end();++it)
it->resize(mat1rows);
for (row = 0; row < mat1rows; row++)
{
for (col = 0; col < mat1columns; col++)
mat2[col][row] = mat1[row][col];
}
}
////////
// third function
void matrixXvector // multiply matrix and vector
(
std::vector< std::vector<double> > inMatrix,
double inVect[3],
double outVect[3]
)
{
int row,col,ktr;
for (row = 0; row <= 2; row++)
{
outVect[row]= 0.0;
for (ktr = 0; ktr <= 2; ktr++)
outVect[row]= outVect[row] + inMatrix[row][ktr] * inVect[ktr];
}
}
So "vector_math" is being called by the main program. It takes inputV as input and the result should be outputV. However, outputV is one of the input arguments, and the function returns void. And similar process occurs later when calling "transposeM" and "matrixXvector".
Why is the output variable one of the input arguments ? How are the results being returned and used for further computation ? How this kind of passing and returning arguments works ?
Since I am a beginner and also have never seen this style of coding, I don't understand how passing parameters and especially giving output works in these functions. Therefore I don't know how to use them and what to expect of them ( what they will actually do ). So I would very much appreciate an explanation that will make these processes clear to me.
EXTRA :
Thank you all for great answers. It was first time I could barely decide which answer to accept, and even as I did it felt unfair to others. I would like to add an extra question though, if anyone is willing to answer ( as a comment is enough ). Does this "old" style of coding input/output arguments have its name or any other expression with which it is referred ?
This is an "old" (but still popular) style of returning certain or multiple values. It works like this:
void copy (const std::vector<double>& input, std::vector<double>& output) {
output = input;
}
int main () {
std::vector<double> old_vector {1,2,3,4,5}, new_vector;
copy (old_vector, new_vector); // new_vector now copy of old_vector
}
So basically you give the function one or multiple output parameter to write the result of its computation to.
If you pass input parameters (i.e. you don't intend to change them) by value or by const reference does not matter, although passing read only arguments by value might be costly performance-wise. In the first case, you copy the input object and use the copy in the function, in the latter you just let the function see the original and prevent it from being modified with the const. The const for the input parameters is optional, but leaving it out allows the function to change their values which might not be what you want, and inhibits passing temporaries as input.
The input parameter(s) have to be passed by non-const reference to allow the function to change it/them.
Another, even older and "C-isher" style is to passing output-pointer or raw-arrays, like the first of your functions does. This is potentially dangerous as the pointer might not point to a valid piece of memory, but still pretty wide spread. It works essentially just like the first example:
// Copies in to int pointed to by out
void copy (int in, int* out) {
*out = in;
}
// Copies int pointed to by in to int pointed to by out
void copy (const int* in, int* out) {
*out = *in;
}
// Copies length ints beginning from in to length ints beginning at out
void copy (const int* in, int* out, std::size_t length) {
// For loop for beginner, use std::copy IRL:
// std::copy(in, in + length, out);
for (std::size_t i = 0; i < length; ++i)
out[i] = in[i];
}
The arrays in your first example basically work like pointers.
Baum's answer is accurate, but perhaps not as detailed as a C/C++ beginner would like.
The actual argument values that go into a function are always passed by value (i.e. a bit pattern) and cannot be changed in a way that is readable by the caller. HOWEVER - and this is the key - those bits in the arguments may in fact be pointers (or references) that don't contain data directly, but rather contain a location in memory that contains the actual value.
Examples: in a function like this:
void foo(double x, double output) { output = x ^ 2; }
naming the output variable "output doesn't change anything - there is no way for the caller to get the result.
But like this:
void foo(double x, double& output) { output = x ^ 2; }
the "&" indicates that the output parameter is a reference to the memory location where the output should be stored. It's syntactic sugar in C++ that is equivalent to this 'C' code:
void foo(double x, double* pointer_to_output) { *pointer_to_output = x ^ 2; }
The pointer dereference is hidden by the reference syntax but the idea is the same.
Arrays perform a similar syntax trick, they are actually passed as pointers, so
void foo(double x[3], double output[3]) { ... }
and
void foo(double* x, double* output) { ... }
are essentially equivalent. Note that in either case there is no way to determine the size of the arrays. Therefore, it is generally considered good practice to pass pointers and lengths:
void foo(double* x, int xlen, double* output, int olen);
Output parameters like this are used in multiple cases. A common one is to return multiple values since the return type of a function can be only a single value. (While you can return an object that contains multiple members, but you can't return multiple separate values directly.)
Another reason why output parameters are used is speed. It's frequently faster to modify the output in place if the object in question is large and/or expensive to construct.
Another programming paradigm is to return a value that indicates the success/failure of the function and return calculated value(s) in output parameters. For example, much of the historic Windows API works this way.
An array is a low-level C++ construct. It is implicitly convertible to a pointer to the memory allocated for the array.
int a[] = {1, 2, 3, 4, 5};
int *p = a; // a can be converted to a pointer
assert(a[0] == *a);
assert(a[1] == *(a + 1));
assert(a[1] == p[1]);
// etc.
The confusing thing about arrays is that a function declaration void foo(int bar[]); is equivalent to void foo(int *bar);. So foo(a) doesn't copy the array a; instead, a is converted to a pointer and the pointer - not the memory - is then copied.
void foo(int bar[]) // could be rewritten as foo(int *bar)
{
bar[0] = 1; // could be rewritten as *(bar + 0) = 1;
}
int main()
{
int a[] = {0};
foo(a);
assert(a[0] == 1);
}
bar points to the same memory that a does so modifying the contents of array pointed to by bar is the same as modifying the contents of array a.
In C++ you can also pass objects by reference (Type &ref;). You can think of references as aliases for a given object. So if you write:
int a = 0;
int &b = a;
b = 1;
assert(a == 1);
b is effectively an alias for a - by modifying b you modify a and vice versa. Functions can also take arguments by reference:
void foo(int &bar)
{
bar = 1;
}
int main()
{
int a = 0;
foo(a);
assert(a == 1);
}
Again, bar is little more than an alias for a, so by modifying bar you will also modify a.
The library of mathematical routines you have is using these features to store results in an input variable. It does so to avoid copies and ease memory management. As mentioned by #Baum mit Augen, the method can also be used as a way to return multiple values.
Consider this code:
vector<int> foo(const vector<int> &bar)
{
vector<int> result;
// calculate the result
return result;
}
While returning result, foo will make a copy of the vector, and depending on number (and size) of elements stored the copy can be very expensive.
Note:
Most compilers will elide the copy in the code above using Named Return Value Optimization (NRVO). In general case, though, you have no guarantee of it happening.
Another way to avoid expensive copies is to create the result object on heap, and return a pointer to the allocated memory:
vector<int> *foo(const vector<int> &bar)
{
vector<int> *result = new vector<int>;
// calculate the result
return result;
}
The caller needs to manage the lifetime of the returned object, calling delete when it's no longer needed. Faililng to do so can result in a memory leak (the memory stays allocated, but effectively unusable, by the application).
Note:
There are various solutions to help with returning (expensive to copy) objects. C++03 has std::auto_ptr wrapper to help with lifetime management of objects created on heap. C++11 adds move semantics to the language, which allow to efficiently return objects by value instead of using pointers.

Passing a vector to a function as void pointer

I have a callback function that takes a void * as a parameter to pass arguments to and I'd like to pass a vector to the function. The function will be called multiple times so after the callback process is complete, I'd like to be able to iterate over all the elements that have been push_back()'ed through the callback.
static void cb(void *data)
{
vector<int> *p = static_cast<vector<int>*>(data); //Attempting to convert *void to vector<int>
p->push_back(1);
}
int main()
{
vector<int> a(10); //Max of 10 push_back()s? vector<int> a; gives memory error.
cb((void*)&a.at(0));
cout << a.at(0); //Gives a random number of 6 digits or higher
}
The issue is that it does not properly have a value of "1" when a.at(0) is called after the callback, just some random number.
Assuming that you cannot change the signature of cb(), try this:
cb(static_cast<void*>(&a));
Here:
cb ((void*)&a.at(0));
you pass a pointer to the first element of the vector, not the vector itself, but here:
vector <int> *p = static_cast <vector <int> *> (data);
you cast passed data to the pointer to a vector, which is probably undefined behavior. If you want to pass pointer to the whole vector, pass like this:
cb ((void *)&a);
If you really want to pass a pointer to an element of the vector, then you should cast like this:
int * = static_cast <int *> (data);
In C++11, you have vector::data:
cb(a.data());

What's the syntax for declaring an array of function pointers without using a separate typedef?

Arrays of function pointers can be created like so:
typedef void(*FunctionPointer)();
FunctionPointer functionPointers[] = {/* Stuff here */};
What is the syntax for creating a function pointer array without using the typedef?
arr //arr
arr [] //is an array (so index it)
* arr [] //of pointers (so dereference them)
(* arr [])() //to functions taking nothing (so call them with ())
void (* arr [])() //returning void
so your answer is
void (* arr [])() = {};
But naturally, this is a bad practice, just use typedefs :)
Extra:
Wonder how to declare an array of 3 pointers to functions taking int and returning a pointer to an array of 4 pointers to functions taking double and returning char? (how cool is that, huh? :))
arr //arr
arr [3] //is an array of 3 (index it)
* arr [3] //pointers
(* arr [3])(int) //to functions taking int (call it) and
*(* arr [3])(int) //returning a pointer (dereference it)
(*(* arr [3])(int))[4] //to an array of 4
*(*(* arr [3])(int))[4] //pointers
(*(*(* arr [3])(int))[4])(double) //to functions taking double and
char (*(*(* arr [3])(int))[4])(double) //returning char
:))
Remember "delcaration mimics use". So to use said array you'd say
(*FunctionPointers[0])();
Correct? Therefore to declare it, you use the same:
void (*FunctionPointers[])() = { ... };
Use this:
void (*FunctionPointers[])() = { };
Works like everything else, you place [] after the name.
I've been building a game engine and have found that I needed dynamically allocated arrays of function pointers.
To address this simply, I've opted for encapsulating the function pointers inside a class.
Here's a simple example:
class Function{
private:
public:
int (*sampleFunction)(int);
};
static int returnInt(int val){
int ret = 20 * i;
return ret;
}
int main(void){
Function *functions; /* V put yours here V */
size_t functionCount = getFunctionCount();
functions = new Function[functionCount];
for(int i=0; i<functionCount; i++)
functions[i].sampleFunction = &returnInt;
for(int i=0; i<functionCount; i++)
functions[i].sampleFunction(i);
return 0;
}
Where can this be useful?
Say that you have a graphical application that you're building that creates buttons out of an undefined number of files in a directory.
Each button has a unique "hitbox" coordinate relative to it's position in an array, and you need to be able to uniquely handle a mouse click for each button.
The Functions class is meant to be placed inside another, more complex, class. Where the point of the function pointer is to make it easier to redefine the button click event when different algorithms are required for the same "form element".