auto versus non-auto for function ptr?


Hi

I'm attempting to try and understand the difference between auto and the non-auto declaration for a pointer to a function that in turn returns a pointer-to-double.

The programme below compiles, but shows "Segmentation fault (core dumped)" at runtime.

Any suggestions for why would be appreciated.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>

// f1() is a function that returns a pointer-to-double 
const double * f1(const double [], int);

// the following 2 declerations are equivalent
const double * (*p1)(const double *, int) = f1;
auto p2 = f1;

int main() {

  const double da[2] = {0.0,0.1};

  std::cout << (*p1)(da,3) << " : " << *(*p1)(da,3) << std::endl;
  std::cout << p2(da,3) << ": " << *p2(da,3) << std::endl;

  return 0;
}

const double * f1 (const double p[], int i) {
  double * d;
  *d = 0.101;
  return d ;
}
Last edited on
1
2
  double * d;
  *d = 0.101;

This code is bad.

The first line create a pointer-to-double, which is pointer at some random memory somewhere.
The second line attempts to write into that random memory somewhere. The operating system spots you trying to write over memory that isn't yours, and stops you with a segFault.

If you make a pointer-to-double, you must make it point to an actual double. For example, like this:

1
2
3
double an_actual_double_object; // create an actual double object
double* d; // create a pointer, pointing at some random memory somewhere
d = &an_actual_double_object; // make the pointer point at an actual double object. 

Thanks for your reply! Have modified as follows:
1
2
3
4
5
const double * f1 (const double p[], int i) {
  double * d;
  d = (double*) &i;
  return d ;
}


no longer errors.
Could you perhaps suggest a better way to typecast from int value to a double pointer?
no longer errors.

That you would see. Yet. Sadly.

You are taking the address of function argument i (which is an integer), casting (with the crude C-style cast) it to be a pointer to double, and returning the pointer from function.

The function arguments are static local variables of the function, allocated from stack, and exist only for the duration of the function call. The address returned by the function points to deallocated memory. Undefined behaviour.

A double might use more memory than an int. If you do use the address of an int as the address of a double, then you are accessing bytes that succeed the bytes of the int too.Undefined behaviour.


What are the function arguments p and i anyway? You do call the function with p=<two-element-array> and i=<3>.
It is ok to study function pointers (p1, p2), but why your test harness is full of undefined behaviour?

Hi

thanks for pointing out the memory locations. I am studying C++ and trying to understand function pointers, without keeping in mind memory, which is is a mistake that leads to undefined behaviour as you mentioned.

I shall make adjustments accordingly. I am using a book to study C++, but often adjust the exercises to a be somewhat more challenging and interesting and only become aware of the consequences as I make mistakes. So thanks for pointing out undefined behaviour consequences.
Topic archived. No new replies allowed.