+ 1
Can anyone explain why this code return segmentation fault?
#include <stdio.h> struct call; typedef struct call * const * c; struct call{ int (*cc)(int); }; int a(int b){ return b; } int main(){ c ccc; (*ccc)->cc = &a; printf("%d\n",(*ccc)->cc(100)); }
6 Respostas
+ 2
XXX,
Big Thanks 🙏
It's been long I've been looking for an easy way to undersand const effects.
+ 1
What are you trying to do the way you creating struct and accessing is not valid
+ 1
First of all, you have made it unncessarily complicated. There is absolutely no reason for this to be done this way.
Anyways, the problem is that type `c` is a pointer to a pointer to `struct c`. As `ccc` is of type `c` which is a pointer, it will have the value of null pointer by default. In the second line of the main() function, you are dereferencing `ccc`, i.e. a null pointer. Dereferencing a null pointer is not allowed and the segmentation fault occurs when you try to do that.
You would first have to make an instance of `struct call`, make a pointer variable that points to it, and then assign the pointer to the variable `ccc` of type `c`. Here, all of your pointers would be valid and the code will work. This is the fixed code
https://code.sololearn.com/cIzfdf11A68k/?ref=app
That again, is unnecessary. It can easily be done like this
https://code.sololearn.com/cf64u99mrKVb/?ref=app
+ 1
XXX,
Just looking for a confirmation about this line ...
typedef struct call * const * c;
This means `c` is a type alias for a pointer to a constant pointer of struct call. Did I get it right? and in this case which one is constant? I'm not too sure how that line is supposed to be read.
+ 1
Ipang
Yeah that is very confusing. Even I was confused. But some quick experimenting led me to this conclusion -
Any type on the left-hand-side of * is the type of the pointer.
Example:
int* const ptr1;
const int* ptr2;
Here, `ptr1` points to `int` but is const which means it cannot be reassigned.
ptr1 = &var; // ERROR: ptr1 is const
*ptr1 = 2; // OK: as ptr1 points to int which is not const
But `ptr2` points to `const int` and is not const itself
ptr2 = &var; // OK: as ptr2 is not const
*ptr2 = 2; // ERROR: ptr2 points to const int
===================
So in this case, it will be
((call)* const)* c;
`c` is NOT const itself, but points to a const pointer to `call`. So
c = &var; // OK
*c = &var2; // ERROR: c points to a const pointer
**c = var3; // OK: *c points to non-const `call`
Hope that was clear.
0
I saw this kind of syntax in a header file and want to give it a try.