sizeof reporting wrong value - c

I'm trying to get a "column" elements count from my own structure using sizeof(_test.header.columns)/sizeof(struct _column). Unfortunately I'm always getting it as 0, because the sizeof(_test.header.columns) is always 4. Here is the code:
struct _column{
char title[40];
int length;
};
struct test_struct{
struct{
struct _column* columns;
}header;
struct{
struct _column* columns;
}details;
struct{
struct _column* columns;
}end;
};
struct test_struct _test = {
.header = {
.columns = {
{
"a",
1,
},
{
"ab",
2,
},
},
},
.details = {
.columns = {
{
"b",
2,
},
{
"bc",
3,
},
},
},
.end = {
.columns = {
{
"c",
3,
},
{
"cd",
4,
},
},
},
};
void testme(){
char buff[20];
itoa(sizeof(_test.header.columns)/sizeof(struct _column),buff,sizeof(buff));
MessageBoxA(NULL,buff,NULL,NULL);
}
please help me to resolve the problem, thanks. Any help would be appreciated.

You might try to do an approach like the following in which you do the same kind of initialization however you include as part of it the column count itself.
struct _column{
char title[40];
int length;
};
struct test_struct{
struct{
struct _column* columns;
int nColumns;
}header;
struct{
struct _column* columns;
int nColumns;
}details;
struct{
struct _column* columns;
int nColumns;
}end;
};
struct _column headerColumns [] = {
{
"a",
1
},
{
"ab",
2
}
};
struct _column detailColumns[] = {
{
"b",
2
},
{
"bc",
3
},
};
struct _column endColumns [] = {
{
"c",
3
},
{
"cd",
4
}
};
struct test_struct _test = {
{ headerColumns, sizeof(headerColumns)/sizeof(headerColumns[0])},
{ detailColumns, sizeof(detailColumns)/sizeof(detailColumns[0])},
{ endColumns, sizeof(endColumns)/sizeof(endColumns[0])}
};

The reason it fails is that you're checking the sizeof on a pointer, which returns the size of the pointer, NOT of the actual Array the memory address points to.
If you know the maximum length of the array, you can declare it as such:
_column[ integerSize ]
But then if you knew the size, you wouldn't be querying it using sizeof, I'd think ;-) You could extend the struct by adding another property of an int type that describes the size of the columns array ?

Related

Initialization of flexible array member is not allowed

I found a GNU C documentation on flexible arrays, and they say that you can initialize them like that:
struct foo { int x; int y[]; };
struct bar { struct foo z; };
struct foo a = { 1, { 2, 3, 4 } }; // Valid.
struct bar b = { { 1, { 2, 3, 4 } } }; // Invalid.
struct bar c = { { 1, { } } }; // Valid.
struct foo d[1] = { { 1, { 2, 3, 4 } } }; // Invalid
But when I try to do the first valid case (with struct a), gcc throws error: Initialization of flexible array member is not allowed. So is this deprecated or is there another way to do it without malloc?

Accessing struct array using double pointers in c

typedef enum
{
ONE = 1,
TWO = 2,
THREE = 3
}Count_t;
typedef enum
{
RED = 0,
BLUE = 1,
GREEN = 2
}Color_t;
typedef struct
{
Count_t Count_en;
Color_t Color_en;
}Grp_t;
Grp_t const Grp_ena[]=
{
{ ONE, RED },
{ TWO, BLUE },
{ THREE, GREEN}
};
typedef struct
{
unsigned int num;
Grp_t * Grp_stp;
}Try_t;
Try_t const Try_sta[] =
{
{ 7, &Grp_ena[0] },
{ 8, &Grp_ena[1] },
{ 9, &Grp_ena[2] },
};
int main()
{
Try_t **p = Try_sta;
}
Using double pointer **p , I want to access the elements of LUT Try_sta. With single dimensional pointer I am able to access the struct array elements. But with 2d pointer I failed to access. Is there any proper way to do it?

mapping structures in struct C

im trying to index number of struct under one struct.
im tying to pass the data in the first struct to the struct pointer but i get return null.
my code is :
struct complex{
char * rNum; /* real number */
char *iNum; /* imaginary number*/
};
struct complex A = {"0","0"};
struct complex B = {"0","0"};
struct complex C = {"0","0"};
struct complex D = {"0","0"};
struct complex E = {"0","0"};
struct complex F = {"0","0"};
struct mapping{
char *key;
struct complex *P;
} complex_map [] = {
{ "A", &A },
{ "B", &B },
{ "C", &C },
{ "D", &D },
{ "E", &E },
{ "F", &F },
};
char call_complex(const char *name) {
int i;
for (i = 0; i < (sizeof(complex_map) / sizeof(complex_map[0])); i++) {
if (!strcmp(complex_map[i].key, name) && complex_map[i].P->rNum) {
complex_map[i].P->rNum;
return 0;
}
}
printf("Invalid\n");
}
and my call function is :
void read_comp(char *str){
printf(" %s",call_complex(str));
}
when i run this code i get return (null)
why?
thanks for helping
Try This:
#include <stdio.h>
struct complex{
char * rNum; /* real number */
char *iNum; /* imaginary number*/
};
struct complex A = {"1","0"};
struct complex B = {"2","0"};
struct complex C = {"3","0"};
struct complex D = {"4","0"};
struct complex E = {"5","0"};
struct complex F = {"6","0"};
struct mapping{
char *key;
struct complex *P;
} complex_map [] = {
{ "A", &A },
{ "B", &B },
{ "C", &C },
{ "D", &D },
{ "E", &E },
{ "F", &F },
};
char call_complex(const char *name)
{
int i;
for (i = 0; i < (sizeof(complex_map) / sizeof(complex_map[0])); i++)
{
if (!strcmp(complex_map[i].key, name) && complex_map[i].P->rNum)
{
return *(complex_map[i].P->rNum); // Correction
}
}
printf("Invalid\n");
}
int main()
{
printf("Got: %c \n",call_complex("A")); // Just example
return 0;
}
Thanks.

gcc complaints about braces in initialiser (nested structs)

In chasing down a very opaque bug, I have been trying to compile with no warnings or errors. This part of my code worked fine, but gcc complains about the braces--it says there are braces missing and extra braces. I usually initialise a bit more sloppily but here I'm being as pedantic as possible with braces for each logical level of inclusion. The only struct I really care about initialising is the last one, the Ccfg. I thought I'd build up to it gradually as it contains nested other structs, but apparently even the ones preceding it are mis-initialized according to gcc.
Here's the code:
#define max_nodes 24
struct Cseg
{
int begin;
int arc;
int end;
};
struct Node
{
struct Cseg exit[4];
};
struct Core
{
int num_circles;
int num_nodes;
struct Node node[max_nodes];
};
struct Ccfg
{
struct Core core;
int dummy1;
int dummy2;
};
int main(void)
{
struct Cseg A = {0,1,2};
struct Node B =
{
{0,1,2}, {1,3,0}, {2,-1,3}, {0,-2,1}
};
struct Node C =
{
{0,1,2}, {1,3,0}
};
struct Core D =
{4, 4,
{
{ {0,1,2}, {1,3,0}, {2,-1,3}, {0,-2,1} },
{ {1,3,0}, {2,1,0}, {3,-2,1}, {2,-1,0} },
{ {3,1,2}, {0,1,2}, {1,-3,0}, {2,-3,1} }
}
};
struct Ccfg E =
{
{2, 2,
{
{ {0,1,1}, {0,2,1} },
{ {1,2,0}, {1,1,0} }
}
}
};
return 0;
}
Some of the initialisations are incomplete; that is deliberate. My real ccfg struct has many more fields but I've simplified it for this post. If someone could let me know what I'm doing wrong I'd appreciate it a lot. Thanks!
EDIT: in my working code, the initialiser for struct Ccfg E omits the innermost braces, and works fine (but gcc still warns me about it). I added them into this test because they seemed logically appropriate, but they actually generate an error--which I don't understand.
You are missing braces in some places. Specifically, if you have an array of structs, the entire array needs to be brace-wrapped; you were just wrapping each struct entry. I just added braces as needed and it works fine now. http://ideone.com/fork/HqxB9R
#define max_nodes 24
struct Cseg
{
int begin;
int arc;
int end;
};
struct Node
{
struct Cseg ex[4];
};
struct Core
{
int num_circles;
int num_nodes;
struct Node node[max_nodes];
};
struct Ccfg
{
struct Core core;
int dummy1;
int dummy2;
};
int main(void)
{
struct Cseg A = {0,1,2};
struct Node B =
{
{ {0,1,2}, {1,3,0}, {2,-1,3}, {0,-2,1} }
};
struct Node C =
{
{ {0,1,2}, {1,3,0} }
};
struct Core D =
{4, 4,
{
{ { {0,1,2}, {1,3,0}, {2,-1,3}, {0,-2,1} } },
{ { {1,3,0}, {2,1,0}, {3,-2,1}, {2,-1,0} } },
{ { {3,1,2}, {0,1,2}, {1,-3,0}, {2,-3,1} } }
}
};
struct Ccfg E =
{
{2, 2,
{
{ { {0,1,1}, {0,2,1} } },
{ { {1,2,0}, {1,1,0} } }
}
}
};
return 0;
}

Initialize sized, static string lists in C

I want to create string lists with a discoverable size and am not sure if I have the right method/syntax. Here is my attempt:
typedef struct {
unsigned int size;
char** list;
} STRLIST;
static STRLIST listMediaType = {
.size = 7,
.list = {
"Book",
"Map",
"Booklet",
"Pamphlet",
"Magazine",
"Report",
"Journal"
},
};
Is this the right approach? Note that I do not want to hardcode the size into the structure because I want to use the same type to define many different lists. For example, imagine the following function:
void printList( STRLIST* pList ){
for( int x = 0; x < pList->size; x++ ) printf( "%s\n", pList->list );
}
It can be done with C99 compound-literals and a slight change:
http://coliru.stacked-crooked.com/a/4497d2645ad21b74
typedef struct STRLIST{
unsigned int size;
char** list;
} STRLIST;
static STRLIST listMediaType = {
.size = 7,
.list = (char*[]){
"Book",
"Map",
"Booklet",
"Pamphlet",
"Magazine",
"Report",
"Journal"
},
};
Alternative for C90 (thus without compound-literals and designated initializers): http://coliru.stacked-crooked.com/a/5cc95d25afc18c91
static char* list[] = {
"Book",
"Map",
"Booklet",
"Pamphlet",
"Magazine",
"Report",
"Journal"
};
static STRLIST listMediaType = {
sizeof list / sizeof *list,
// Used sizeof to avoid manually typing the lists length
list,
};
As an aside, an array with a sentinel-NULL is far simpler than a counted array.
Does not even need a new type.
static char* list[] = {
"Book",
"Map",
"Booklet",
"Pamphlet",
"Magazine",
"Report",
"Journal",
0
};
void printList(char** pList){
while(*pList) printf( "%s\n", *pList++);
}
You may check this code:
#include <stdio.h>
typedef struct {
unsigned int size;
char* list[];
} STRLIST;
static STRLIST listMediaType = {
7,
{
"Book",
"Map",
"Booklet",
"Pamphlet",
"Magazine",
"Report",
"Journal"
}
};
int main() {
printf("struct size: %d\n", listMediaType.size);
int i;
for (i = 0; i < listMediaType.size; i++)
printf("struct elem[%d] = \"%s\"\n",
i,
listMediaType.list[i]);
return 0;
}
I think there are 2 problems in your approach:
Is TYPEDEF syntactic correct in C? I think you should write it in lowercase.
If you want to initialize a struct, just use the brace and without .attributes
Hope this one will help.
Thanks

Resources