Why do I get the "identifier "a" is undefined" in a function where I have a as a parameter? - c++

In the following code:
void benchmark(string desc, int(*pf)(int a[50])) {
printf("\n Benchmark for %s", desc.c_str());
double tStart = omp_get_wtime();
int result = pf(a[50]);
double tFinal = omp_get_wtime();
printf("\n\t Final result: %d", result);
printf("\n\t Duration: %f (s)", tFinal - tStart);
int main() {
int i, b;
int a[50];
for (i = 0; i < 50; i++)
{
b = rand() % 10000 + 1;
a[i] = b;
}
benchmark("Parallel solution without mutex for counting primes", Squential);
benchmark("Parallel solution with load balancing", Parallel1);
benchmark("Parallel solution with load balancing", Parallel2);
}
On line "int result = pf(a[50]);" the compiler says "identifier "a" is undefined" although I listed it in the parameters list. It may have something to do with the pointer, I'm not used to working with pointers.

This does not have a parameter a
void benchmark(string desc, int(*pf)(int a[50])) {
This has the parameters:
* desc: Type -> string
* pf: Type -> A function (pointer) that returns int and takes an array of int
This is a function pointer type:
int (*pf)(int a[50])
^^ This is the name of the paramter.
// This is the type
int (*)(int[50])
// This is a pointer to a function that returns an `int`
// and takes `int[50]` as a parameter.
Just to get this copiling do this:
int result = pf(a[50]);
// change into this:
int data[50]; // or get this from somewhere else.
int result = pf(data);

Related

what happens when a pointer is passed as a pointer to a pointer inside another function?

So can someone explain what would happen if I pass ...*p as the argument name for the foo function
int main()
{
int i = 10;
int *const p = &i;
foo(&p);
printf("%d\n", *p);
}
void foo(int **p)
{
int j = 11;
*p = &j;
printf("%d\n", **p);
}
Don't do that. You'll have a pointer to an undefined memory location on the stack. Any other function call between foo(&p); and printf("%d\n", *p); is bound to overwrite that memory location with new data.
Let's look at a simple example here! We have a function print_address, which takes an address and prints it. We're gonna print the address of an int, as well as the address of a pointer to that int, and a pointer of a pointer to that int.
#include <stdio.h>
void print_address(void* addr) {
printf("Address: %p\n", addr);
}
int main()
{
int value = 0;
int* value_ptr = &value;
int** value_ptr_ptr = &value_ptr;
print_address(&value);
print_address(&value_ptr);
print_address(&value_ptr_ptr);
return 0;
}
When I run this code, I get the following output:
Address: 0x7fffa4936fec
Address: 0x7fffa4936ff0
Address: 0x7fffa4936ff8
The first address is to value, the second address is to value_ptr, and the third address is to value_ptr_ptr. Each address is a little higher than the previous one, because each variable has been stored a little higher up on the stack.
The same thing happens with function calls. When we call a function, the memory for all the local variables in that function is stored a little higher up on the stack then the memory for all the local variables in the current function:
#include <stdio.h>
void print_address(void* addr) {
printf("Address: %p\n", addr);
}
void f3(int*** ptr) {
print_address(ptr);
}
void f2(int** ptr) {
print_address(ptr);
f3(&ptr);
}
void f1(int* ptr) {
print_address(ptr);
f2(&ptr);
}
int main()
{
int value = 0;
f1(&value);
return 0;
}
This time when I ran it, the output was
Address: 0x7ffeca71dc2c
Address: 0x7ffeca71dc08
Address: 0x7ffeca71dbe8
If you notice, the gaps between addresses are higher, but that's because of the extra stack space it takes to do a function call.
j is destoyed after exiting foo, so doing anything with it after foo calling in main is incorrect, until you reset it on another object (I mean printf("%d\n", *p)).
Well, what you're doing is passing pointer on pointer on integer.
As you could see, pointers are often used to pass arrays:
void print_array(int* a, int n) {
for (int i = 0; i < n; i++)
printf("%d ", a[i]);
printf("\n");
}
And pointers on pointers are used to pass two-dimensional arrays, for example in int main(int argc, char** argv) { ... } argv is array of strings or array of arrays of char-s.
You can't pass *p, but let's say you could...
It looks like you are trying to get your function to update a parent variable - and passing &p is the correct way to do it. But you are adding one too many dereference. I highly recommend you read this: https://boredzo.org/pointers/
// Let's assume you only have 4 memory locations for variables: 1 2 3 and 4.
// let's call these m[1] m[2] m[3] and m[4]
// i is at 1, p is at 2, j is at 3, and the p inside the function is at 4.
// let's call that second p, q rather
// so you have: m[1..4] = { i, p, j, q }
// now execute the code in your head:
int main()
{
int i = 10; // m[1] = 10
int *const p = &i; // m[2] = 1
foo(&p); // foo(2)
printf("%d\n", *p); // printf m[2]
}
void foo(int **q) // q = m[m[2]] = m[1] = 10
{
int j = 11; // m[3] = 11
*q = &j; // m[10] = 3 // segfault!
printf("%d\n", **q); // printf m[m[10]] = m[3] = 11 // if it didnt' segfault
}
It looks like this is what you are trying to do:
#include <stdio.h>
void b(int *q,int n) {
*q=n;
}
int main() {
int i=123;
int *p=&i; // *p and i are now synonymous
printf("%i ",i);
printf("%i ",*p); // same thing
b(p,111);
printf("%i ",i);
b(&i,111);a // same thing
printf("%i ",i);
}

Error in program with structures and pointers (Structures, C++)

I have a structure , which contains three variables under the object list.-Names, registration nos, amount.
struct vendor
{
int reg, amt;
char add[30];
}list[10];
I have made a function to find the minimum amount(amt) ,using the referencing concept.
int low(vendor *p, int n)
{
int i;
min = (p->amt);
for(i =1;i<n;i++)
{
if(min > *(p->amt))
{
min = *(p->amt);
}
p++;
}
return min;
}
In the main I have included the syntax:
low(list, n);
I am getting an error:
Invalid argument of unary '*' operator.
I have tried using the dot operator also and is not working.
This is my first program in pointers in structs with functions.
Can you please point out the error in the code.
Thank You very much
Anupam
(Update) the full code:
#include <iostream>
using namespace std;
struct vendor
{
int reg, amt;
char add[30];
}list[10];
int low(vendor *p, int n)
{
int i;
min = (p->amt);
for(i =1;i<n;i++)
{
if(min > (p->amt))
{
min = (p->amt);
}
p++;
}
return min;
}
int main()
{
int i;
int fa;
int n,fr;
cin >> n;
for(i =0;i<n;i++)
{
cin >>list[i].reg>>list[i].add>>list[i].amt;
// Enter reg no. , address and amount.
}
low(list, n); // Calling function
for(i = 0;i<n;i++)
{
if(fr == list[i].amt)
// This is to check for position of least amount.
// For printing the reg no. and address of least amt.
{
fa = i;
}
}
cout << fr <<"\n" << fa <<endl;
// print the reg no. and address of least amt.
}
Errors:
Overloaded function with no contextual type information.
Invalid operands of types <unresolved overloaded function
Cannot resolve overloaded function
The declaration for min is missing in low() function.
int min = (p->amt);
This should help you compile your code.
p is a pointer to a vendor. *p is a vender. p->amt is an int.
So when you want the amt of an object that is pointed to by p you can do it in one of two ways: p->amt or (*p).amt
You fix your code by using p->amt or (*p).amt. *p->amt or *(p->amt) are invalid.
p is a object of vendor which type is pointer . "->" is used to use pointer object . So use p->amt .
you can also use (*p).amt .
Updated Answer :
decleration of min is missing . please use this :
int min = p->amt ;
or use this :
int min = (*p).amt;

cannot convert 'double(_cdecl*)()' to 'double'

As an assignment I have to write a code that takes user inputs, performs an operation with them, then prints them to the screen. However, I keep getting an error on line 18 where I call FunctionMultiply saying that the function cannot convert 'double(_cdecl*)()' to 'double'. I searched for this type of problem but it seems like all of them have to do with arrays which aren't in my code. How can I fix this?
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <ctype.h>
int GetInt(void);
double GetDouble();
char GetLetter(void);
double FunctionMultiply(int, double);
int FunctionCharacter(char);
int main()
{
GetInt();
GetDouble();
GetLetter();
FunctionMultiply(GetInt, GetDouble);
FunctionCharacter(GetLetter);
printf("%f", FunctionMultiply);
printf("%c", FunctionCharacter);
return 0;
}
int GetInt(void)
{
int integer;
printf("Enter an integer\n");
scanf("%i", &integer);
return integer;
}
double GetDouble()
{
double dub;
printf("Enter a floating point number\n");
scanf(" %lf", &dub);
return dub;
}
char GetLetter(void)
{
char letter;
printf("Enter a letter\n");
scanf(" %c", &letter);
return letter;
}
double FunctionMultiply(int arg1, double arg2)
{
double product = arg1 * arg2;
return product;
}
int FunctionCharacter(char letter)
{
if (toupper(letter) <= 'M')
{
return 0;
}
else
{
return 1;
}
}
I think you are confusing function identifiers with storage. You have just called a bunch of functions at the beginning and not stored their results in anything.
It appears that you expect using the function identifier on its own will give you the result of the last call to that function. But it does not.
Here is how you would store the return values and use them later:
int my_int = GetInt();
double my_double = GetDouble();
char my_char = GetLetter();
double multiply_result = FunctionMultiply( my_int, my_double );
char char_result = FunctionCharacter( my_char );
printf( "%f", multiply_result );
printf( "%c", char_result );
Modify your main() like this:
int main()
{
int i = GetInt();
double d = GetDouble();
char c = GetLetter();
double a = FunctionMultiply(i, d);
char c = FunctionCharacter(c);
printf("%f", a);
printf("%c", c);
return 0;
}
Your problem is that you are passing function names rather than calling them. i.e. GetInt instead of GetInt().
It looks like you weren't paying attention to the lessons or examples showing how to use functions.
GetInt();
This calls the GetInt function, and ignores its return value.
GetDouble();
This calls the GetDouble function, and ignores its return value.
GetLetter();
This calls the GetLetter function, and ... you know the score by now.
FunctionMultiply(GetInt, GetDouble);
This is just nonsense. You're trying to call the FunctionMultiply function, passing the functions GetInt and GetDouble as arguments. You need to pass it an int and double, but you don't have an int and a double because you didn't store the results of GetInt and GetDouble anywhere.
You should have done this:
int i = GetInt();
double d = GetDouble();
char l = GetLetter();
Now you have variables i, d and l that hold the results of those function calls, so you can pass them in to other functions:
FunctionCharacter(i, d);
You seem to be under the impression that the name of a function magically changes to the result of the call, after you've called the function once.
It doesn't. The function call expression itself is the result of the call.
Instead of
ReturnADouble();
// call ^ and value v somehow separated? Why did you ever think that?
double result = ReturnADouble;
But according to the language rules, ReturnADouble is still the name of a function, and the compiler righteously complains when you give the name of a function when you should be giving a numeric value.
Your code should read more like
double result = ReturnADouble();
// ^ this call results in a value

Interpolation error with gsl_interp_linear

I need to interpolate a modified Bessel function and I use for that the function gsl_spline_eval(). I get a 'gsl: interp.c:145: ERROR: interpolation error' with the following code:
#define MAXPOINTS 10000
int main()
{
double nu;
gsl_function F;
F.function = &sync;
F.params =0;
size_t size;
double table[2][MAXPOINTS];
size = read_table(table[0],table[1]);
gsl_interp_accel *acc = gsl_interp_accel_alloc ();
gsl_spline *spline = gsl_spline_alloc (gsl_interp_linear, 5401);
gsl_spline_init(spline,table[0],table[1],size);
cout <<" nu: "<< nu<< " GSL_FN_EVAL(&F,nu): "<<nu*GSL_FN_EVAL(&F,nu)<<endl;
return 0;
}
Where sync() returns the integral of the function sync_kern() using the gsl function gsl_integration_qag(). The function read_table() is defined as follow:
size_t read_table(double *xa, double *ya)
{
size_t datapoints;
datapoints = 5401;
double x[] = {
1.388794e-11,
1.395756e-11,
... };
double y[] = {
5.166810e-04,
5.175428e-04,
...
};
int i = 0;
while(i<datapoints){
xa[i]=log(x[i]);
ya[i]=log(y[i]);
i++;
}
return datapoints;
}
The function sync_kern() is the following:
double sync_kern(double gamma, void *params)
{
struct func_params *part= (struct func_params *)params;
double result;
double P,x, nuc, nu_0;
double nu = *(double *)params;
gamma = exp(gamma);
nu_0 = (3*E_COULOMB*B*sqrt(2/3.0))/(4.0*M_PI*M*C);
nuc = nu_0*sq(gamma);
x = nu/nuc;
gsl_interp_accel *acc = gsl_interp_accel_alloc ();
gsl_spline *spline = gsl_spline_alloc (gsl_interp_linear, 5401);
/* double table[2][MAXPOINTS];
size = read_table(table[0],table[1]);
gsl_interp_accel *acc = gsl_interp_accel_alloc ();
gsl_spline *spline = gsl_spline_alloc (gsl_interp_interp, 5401);
gsl_spline_init(spline,table[0],table[1],size); */
P = gsl_spline_eval(spline,log(x),acc);
result = exp(P)*f(gamma)*gamma;
return(result);
}
When I include the lines
/* double table[2][MAXPOINTS];
size = read_table(table[0],table[1]);
gsl_interp_accel *acc = gsl_interp_accel_alloc ();
gsl_spline *spline = gsl_spline_alloc (gsl_interp_interp, 5401);
gsl_spline_init(spline,table[0],table[1],size); */
in the function sync_kern() and not in main() then it works: I get the right value of GSL_FN_EVAL(&F,nu) but it takes of course too much time...
I hope my message wasn't too long...I am not a great expert of c++ and I've look all the aspects of the problem and I still don't understand where it comes from...Does someone have any idea?
Please don't hesitate do ask me if you need any further informations.
Thanks a lot for your help!
Maybe I should precise that I got my code from my supervisor's code. Which is slightly different:
int main(int argc,char *argv[])
{
FILE *fp;
struct func_params params;
size_t size;
int i;
/* initializing parameters */
initialize(argc, argv, &params);
/* Interpolation of Synchrotronfunction F(x) */
double table[2][MAXPOINTS];
size = read_table(table[0],table[1]); /*Tabelle fuer Interpolation einlesen aus create_table.c*/
params.acc = gsl_interp_accel_alloc();
params.spline = gsl_spline_alloc(gsl_interp_linear, size);
gsl_spline_init(params.spline,table[0],table[1],size);
...
return (0);
}
double
sync_kern(double gamma, void *params)
{
struct func_params *part= (struct func_params *)params;
double result;
double P,nu_c,x;
gamma = exp(gamma);
nu_c = part->nu_0*sq(gamma);
x = part->nu_s/nu_c;
P = gsl_spline_eval(part->spline,log(x),part->acc); /*Aus Interpolation: Pointer auf spline */
result = exp(P)*f(gamma)*gamma;
return(result);
}
Where spline and acc are defined in a file.h:
struct func_params
{
gsl_spline *spline;
gsl_interp_accel *acc;
...
}
void initialize(int argc, char *argv[], void *params)
{
struct func_params *part= (struct func_params *)params;
/* Default values for parameters: */
part->gmin=1.0e7/M_E_EV;
part->gamma=1.0e10/M_E_EV;
part->gmax=2.0e18/M_E_EV; /*Integrationgrenzen fuer gamma festlegen*/
part->nu=1e-9/H_EV;
...
}
I defined spline and acc in my function sync_kern() and him in a structure. Does someone has an idea where the error can come from?
The function read_table() gives the arrays 'x[]' and 'y[]' used for
the interpolation
double table[2][MAXPOINTS];
size = read_table(table[0],table[1]);
You define an array of doubles, but don't initialize it. It contains random values. So likely it runs with absurd results.
You pass two values to read_table(). If you want the function to change them, the definition of this function should be
size_t read_table(double& val1, double& val2);
Review your code. There are some vars without declaration (nu_0, nuc, acc)
EDIT
After you edited the question, I see how read_table() is defined. It uses two pointers. You have an only array, two dimensions, fixed size. Because of this fixed size, it's OK to pass the array by using two pointers, table[0] and table[1].
double table[2][N] is same as double** table. So passing table[1] is passing a pointer to an array[N].
The gsl error is due to this code at gsl:interp.c
https://github.com/ampl/gsl/blob/master/interpolation/interp.c
if (x < interp->xmin || x > interp->xmax)
{
GSL_ERROR_VAL("interpolation error", GSL_EDOM, GSL_NAN);
}
It seems you are trying an interpolation out of limits (called "extrapolation")

Confusion about pointer to an array as a function parameter

In my textbook about c++ I have the following code example:
using std::cout;
using std::endl;
int main() {
int aArr[4] = { 3,4,2,3 };
int bArr[3] = { 2,3,1 };
cout << "Append: " << endl;
printArray(aArr, 4); cout << " + "; printArray(bArr, 3);
int* cArr = append(&aArr, bArr);
cout << " = "; printArray(cArr, 7); cout << endl;
return 0;
}
Does the "&" symbol in front of "aArr" in the call to append in main mean that the address of aArr is passed, or that a reference to aArr is passed.
The question then asks for me to implement a function append which takes two arrays: the first array (in the first argument) of size 4 by array pointer and the second array (in the second argument) of size 3 by reference and returns a pointer to an array of size 7. I have declared that function as (in the appropriate header file)
int* append( int foo[4], int (&secondArray) [3] );
Has the author perhaps misplaced the order of the "&" symbol in the append method (that it should be in front of "bArr")?
The compiler can help you out in cases like this.
Lets assume that this is the function prototype for your append function:
int* append( int foo[4], int (&secondArray) [3]);
I can test this out with this simple bit of code:
int* append( int foo[4], int (&secondArray) [3])
{
return 0;
}
int main() {
int aArr[4] = { 3,4,2,3 };
int bArr[3] = { 2,3,1 };
int* cArr = append(&aArr, bArr);
return 0;
}
But the compiler doesn't like this, failing with this error:
test.cpp(9): error C2664: 'int *append(int [],int (&)[3])':
cannot convert argument 1 from 'int (*)[4]' to 'int []'
As you can see it doesn't like the &aArr argument 1 at line 9 as it does not match the argument 1 defined by the function at line 1. From the error message it is even nice enough to give a reason why it thinks they don't line up.
Now using the hint from the compiler it is clear the function should in fact look like this:
int *append(int (*foo)[4], int secondArray[3])
{
return 0;
}
int main() {
int aArr[4] = { 3,4,2,3 };
int bArr[3] = { 2,3,1 };
int* cArr = append(&aArr, bArr);
return 0;
}
With that change the compiler is happy to accept the code as correct.
Now comparing the two you can see the difference is in the first case the first argument was passed as an array of 4 integers, whereas in the second case it is passed as the address of an array of four integers.
Just from the english you can tell these are two very different things.
EDIT: Here is an extension of that example that shows how to access the data inside the function.
#include <stdio.h>
int *append(int (*foo)[4], int secondArray[3] )
{
int *foo1 = *foo;
for (int i = 0; i < 4; ++i)
{
printf("foo: %d\n", foo1[i]);
}
for (int j = 0; j < 3; ++j)
{
printf("secondArray: %d\n", secondArray[j]);
}
return 0;
}
int main() {
int aArr[4] = { 3,4,2,3 };
int bArr[3] = { 12,13,11 };
int* cArr = append(&aArr, bArr);
return 0;
}
Compiling an running this code produces this output:
foo: 3
foo: 4
foo: 2
foo: 3
secondArray: 12
secondArray: 13
secondArray: 11