I have tried;
void *malloc(unsigned int); struct deneme { const int a = 15; const int b = 16; }; int main(int argc, const char *argv[]) { struct deneme *mydeneme = malloc(sizeof(struct deneme)); return 0; }
And this is the compiler's error:
gereksiz.c:3:17: error: expected ':', ',', ';', '}' or '__attribute__' before '=' token
And, also this;
void *malloc(unsigned int); struct deneme { const int a; const int b; }; int main(int argc, const char *argv[]) { struct deneme *mydeneme = malloc(sizeof(struct deneme)); mydeneme->a = 15; mydeneme->b = 20; return 0; }
And this is the compiler's error:
gereksiz.c:10:5: error: assignment of read-only member 'a' gereksiz.c:11:5: error: assignment of read-only member 'b'
And neither got compiled. Is there any way to initialize a const variable inside a struct when allocation memory with malloc?
No, using const in such a way is not a good idea. By declaring your structure fields as const , you are declaring an intention that those fields will never change their value.
To initialize the const value using constructor, we have to use the initialize list. This initializer list is used to initialize the data member of a class. The list of members, that will be initialized, will be present after the constructor after colon. members will be separated using comma.
You can const individual members of a struct. Declaring an entire instance of a struct with a const qualifier is the same as creating a special-purpose copy of the struct with all members specified as const .
In C++ the const keyword has been improved and you can declare real const values. That's why it has to be initialized before compiling the code. The rule is slightly different: to be used in an integral constant expression, the initialization must be visible to the compiler.
You need to cast away the const to initialize the fields of a malloc'ed structure:
struct deneme *mydeneme = malloc(sizeof(struct deneme)); *(int *)&mydeneme->a = 15; *(int *)&mydeneme->b = 20;
Alternately, you can create an initialized version of the struct and memcpy it:
struct deneme deneme_init = { 15, 20 }; struct deneme *mydeneme = malloc(sizeof(struct deneme)); memcpy(mydeneme, &deneme_init, sizeof(struct deneme));
You can make deneme_init
static and/or global if you do this a lot (so it only needs to be built once).
Explanation of why this code is not undefined behaviour as suggested by some of the comments, using C11 standard references:
This code does not violate 6.7.3/6 because the space returned by malloc
is not "an object defined with a const-qualified type". The expression mydeneme->a
is not an object, it is an expression. Although it has const
-qualified type, it denotes an object which was not defined with a const-qualified type (in fact, not defined with any type at all).
The strict aliasing rule is never violated by writing into space allocated by malloc
, because the effective type (6.5/6) is updated by each write.
(The strict aliasing rule can be violated by reading from space allocated by malloc
however).
In Chris's code samples, the first one sets the effective type of the integer values to int
, and the second one sets the effective type to const int
, however in both cases going on to read those values through *mydeneme
is correct because the strict-aliasing rule (6.5/7 bullet 2) permits reading an object through an expression which is equally or more qualified than the effective type of the object. Since the expression mydeneme->a
has type const int
, it can be used to read objects of effective type int
and const int
.
Have you tried to do like this:
int main(int argc, const char *argv[]) { struct deneme mydeneme = { 15, 20 }; struct deneme *pmydeneme = malloc(sizeof(struct deneme)); memcpy(pmydeneme, &mydeneme , sizeof(mydeneme)); return 0; }
I have not tested but the code seems correct
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With