Suppose I have a pointer to pointer to function taking int and returning int*.
int* (**ptr)(int) //i hope i'm not wrong here
How should I alloc memory for that pointer using new? And how can I create an array of pointers to functions with new?
I was trying something like this:
int* (**ptr)(int) = new int* (*)(int);
but it shows "expected primary-expression before ‘)’ token"
Here is a demonstrative program that shows how the array can be declared with a typedef and without a typedef.
#include <iostream>
int * func1(int value)
{
static int x = value;
return &x;
}
int * func2(int value)
{
static int x = value;
return &x;
}
int * func3(int value)
{
static int x = value;
return &x;
}
int main()
{
const int N = 3;
typedef int * (*PFunc)(int);
PFunc *ptr = new PFunc[N] { func1, func2, func3 };
int* (**ptr1)(int) = new ( int* (*[N])(int) ){ func1, func2, func3 };
for (int i = 0; i < N; i++)
{
std::cout << *ptr[i]( i ) << std::endl;
}
std::cout << std::endl;
for (int i = 0; i < N; i++)
{
std::cout << *ptr1[i]( i ) << std::endl;
}
std::cout << std::endl;
return 9;
}
The correct syntax to create an array of functions pointers is as follows:
int* (**ptr)(int) = new (int*(*[5])(int));
This creates an array of 5 function pointers, where each function pointer is of type int *(*)(int).
This can be simplified with a typedef:
typedef int *(*fp)(int);
fp *ptr2 = new fp[5];
Related
This question already has answers here:
pass by reference and value with pointers [duplicate]
(5 answers)
Closed 3 years ago.
I am not a beginner in C/C++ but I can't seem to find what is wrong with this piece of c++ code. I also tried it with the c equivalent(malloc) and I get the same result.
#include <iostream>
void foo(int *n) {
n = new int;
*n = 11;
}
int main() {
int *num = NULL;
foo(num);
std::cout << num << '\n';
if (num) {
delete num;
}
return 0;
}
n is a pointer that is being passed by value, so any modifications made by the function to the pointer itself are not applied to the caller's variable. And as such, you are leaking memory since you are new'ing memory that you are not able to delete afterwards.
To do what you are attempting, you need to pass n by reference instead:
void foo(int* &n) {
n = new int;
*n = 11;
// or simply:
// n = new int(11);
}
Otherwise, you should change your function to return the new pointer instead of outputting it via a reference parameter:
#include <iostream>
int* foo() {
int *n = new int;
*n = 11;
return n;
// or simply:
// return new int(11);
}
int main() {
int *num = foo();
std::cout << num << '\n';
delete num;
return 0;
}
That being said, in C++11 and later, you should be using std::unique_ptr instead of a raw pointer:
#include <iostream>
#include <memory>
void foo(std::unique_ptr<int> &n) {
n.reset(new int(11));
// or:
// std::unique_ptr<int>(new int(11)).swap(n);
// or, in C++14 and later:
// n = std::make_unique<int>(11);
}
int main() {
std::unique_ptr<int> num;
foo(num);
std::cout << num.get() << '\n';
return 0;
}
#include <iostream>
#include <memory>
std::unique_ptr<int> foo() {
return std::unique_ptr<int>(new int(11));
// or, in C++14 and later...
// return std::make_unique<int>(11);
}
int main() {
std::unique_ptr<int> num = foo();
std::cout << num.get() << '\n';
return 0;
}
I was studying for my C++ exam and noticed that my answer differs from the solution. The question was to write a method that gives the biggest double or string (by size) from an array with templates. I know that by passing the array as a parameter you give a pointer to the first index.
I'm really confused on where I should write the "const" to signify that the array is not being altered though. Also the code contains 2 dutch words, "grootste" means "biggest", and "grootte" just means "size". PS: max= maximum
this is my solution:
#include <iostream>
using namespace std;
template <typename T>
T grootste(T const [],int);
double grootte(double);
int grootte(const string&);
int main(){
double getallen[5] = {5.5,7.7,2.2,9.8,9.9};
string woorden[3] = {"geloof","hoop","de liefde"};
cout << "Biggest number " << grootste(getallen,5) << "." << endl;
cout << "Longest of 3 strings " << grootste(woorden,3) << "." <<
endl;
return 0;
}
int grootte(const string &a){
return a.size();
}
double grootte(double d){
return d;
}
template <typename T>
T grootste (T const arr[], int lengte){
T max=arr[0];
for(int i=1;i<lengte;i++){
if(grootte(arr[i])>grootte(max)){
max = arr[i];
}
}
return max;
}
this is the solution my course gives me, there was no main included and the other methods were the same.
I wrote the solution again but now it's a literal copy from the pdf the students recieved. I'm sorry for the spacing, i have no idea why it does that.
template < class T >
T grootste ( const T * array , int lengte ){
T gr = array [0];
for ( int i =1; i < lengte ; i ++) {
if ( grootte ( gr ) < grootte ( array [i ]) ){
gr = array [i ];
}
}
return gr ;
}
These parameters are all equivalent:
const T p[]
T const p[]
const T *p
T const *p
Which one to choose is a matter of taste and convention.
I always get confused when types get complex. Use a typedef/using statement to make it clear what you mean exactly.
using intptr = int*; //pointer to int
void foo(const intptr arr ) { // a const pointer to int
arr[0] = 32;
// arr = nullptr; //This will fail
}
using cint = const int;
void bar(cint* arr){ // pointer to const int
//arr[0] = 42; //This will fail
arr = nullptr;
}
template<class T>
struct Types {
using Tptr = T*;
using ConstT = const T;
};
template<class T>
T grootste(typename Types<T>::constT* arr, int length) { //pointer to const T, i.e Ts in the array cannot change
//...
}
How do i access the array in the main using the reference arrref
The memory leak in the code below is intended to know valgrind tool.But i am not able to compile the code below
#include <iostream>
int& func();
int main()
{
int &arrref = func();
std::cout<<arrref[1];//Error
std::cout<<&arrref[1];//Error
}
int& func()
{
int *a = new int[10];
for(int i = 0;i<10 ;++i)
a[i] = i*2;
return *a;
}
Thanks
The syntax needed is (&arrref)[1]. That refers to the second element of an array.
But make sure that the reference returned from func indeed refers to the first element of an array with sufficient number of elements.
To communicate clearly that func returns a reference to an array you may like to return a range, e.g.:
#include <iostream>
#include <boost/range/as_array.hpp>
boost::iterator_range<int*> func() {
static int array[2] = {1, 2};
return boost::as_array(array);
}
int main() {
auto array = func();
std::cout << array[0] << '\n';
std::cout << array[1] << '\n';
for(auto const& value: func())
std::cout << value << '\n';
}
Outputs:
1
2
1
2
Firstly it is not a good idea access local variables of one function in some other functions.
The function return type is int& which says that you want to return a reference to an int variable.
If you want to access the array local array 'a' then the function should be rewritten as -
#include <iostream>
int* func();
int main()
{
int *arrref = func();
std::cout<<arrref[1];//Error
std::cout<<&arrref[1];//Error
}
int *func()
{
int *a = new int[10];
for(int i = 0;i<10 ;++i)
a[i] = i*2;
return a;
}
Alternatively you can also use vectors -
#include<iostream>
#include<vector>
std::vector<int>& func();
int main()
{
std::vector<int>& arrref = func();
std::cout<<arrref[1];//Error
std::cout<<&arrref[1];//Error
}
std::vector<int>& func()
{
std::vector<int> a(10);
for(int i = 0;i<10 ;++i)
a[i] = i*2;
return a;
}
I want to receive a VECTOR in my main function. The code is this.
int myfunction(void);
int main(){
int p = myfunction(void);
std::cout << p[2] << std::endl;
};
int myfunction(void){
int new array[4]={0,1111,2222,3333};
int *p;
p = array;
return p;
};
In C++ you would do:
std::vector<int> myfunction();
int main(){
std::vector<int> p = myfunction();
std::cout << p[2] << std::endl;
}
std::vector<int> myfunction(){
return std::vector<int>{0,1111,2222,3333};
}
And in C you could do:
int* myfunction(void);
int main(void){
int* p = myfunction();
printf("%d\n", p[2]);
free(p);
}
int* myfunction(void){
int tmp[] = {0,1111,2222,3333};
int* array = (int*)malloc(sizeof(tmp));
memcpy(array, &tmp, sizeof(tmp));
return array;
}
Now if you have trouble with this code, I'd recommend you go pick a good C or C++ book (whichever it is you're interested in) and read up on the basics of the language, because you seem really confused.
Lets say in my main method, I declare a const int array pointer pointing to an array created on the heap. I then want to initialize it's values (using the memory address) in a constructor TryInitialize() and then print them out. This is not working and I'm wondering what I'm doing wrong? Thanks!
#include "stdafx.h"
#include "part_one.h"
#include <string>
#include <iostream>
using namespace std;
string createTable(unsigned int* acc, double* bal, int n) {
string s;
char buf[50];
for (int i = 0; i < n; i++) {
sprintf_s(buf,"%7u\t%10.2f\n",acc[i], bal[i]);
s += string(buf);
}
return s;
}
int _tmain(int argc, _TCHAR* argv[])
{
const int *tempInt = new const int[4];
TryInitialize(tempInt);
std::cout << tempInt[1] << endl;
system("pause");
return 0;
}
And here is my code for my constructor:
#include "part_one.h"
TryInitialize::TryInitialize(void) {
}
TryInitialize::TryInitialize(int constInt[]) {
constInt[0] = 8;
constInt[1] = 0;
constInt[2] = 0;
constInt[3] = 8;
}
You should not change a const value.
For what you trying to accomplish I'd recommend declaring a non-const pointer and a const pointer and assigning the non-const one to the const one after the initialization:
int _tmain(int argc, _TCHAR* argv[])
{
const int *tempTempInt = new int[4];
TryInitialize(tempInt);
const int* const tempInt = tempTempInt;
std::cout << tempInt[1] << endl; //this is now constant.
system("pause");
return 0;
}
Also pay attention where you put the const in the pointer declaration:
const int* const tempInt = tempTempInt;
In the declaration above the second const means that you cannot change the pointer; the first const means that you cannot change the pointed value(s).
You declare the pointer as const int*. The const modifier means that you cannot change the array values.
Either remove the const, or create an initializer method for it that can allocate the array and return it (unlike a constructor).
const int* init_my_array()
{
int * ret = new int[4];
ret [0] = 8;
ret [1] = 0;
ret [2] = 0;
ret [3] = 8;
return ret;
}
...
const int *tempInt = init_my_array();
You don't. Why? Because if it's const, then it can't be changed once the object has been constructed. Note: Even setting it is effectively changing its value from its uninitialized value, which goes against the definition of const to begin with.