?
Solved

Returning the number of items in a C struct

Posted on 2014-03-04
10
Medium Priority
?
480 Views
Last Modified: 2014-03-05
I haven't used C in about an eternity, I'm very rusty with it. I'm trying to make some modifications to someone else's code, specifically, I'm trying to change the way the previous author looped through the items in a struct.

The struct is defined in tables.c as follows:
const struct my_type my_struct[] {
    ...
};

Open in new window


In process.c, he then loops through the contents of that. The problem is that he does it using a hardcoded number. So I'm trying to change it to this:
for (i = 1; sizeof(my_struct); i++) {
   ...
}

Open in new window


When I try to compile my code, I get this error:

error: invalid application of 'sizeof' to incomplete type 'const struct my_type[]'

Any ideas as to what I'm missing here or how I can make this work more efficiently than using a hard-coded max with for()?
0
Comment
Question by:elorc
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 2
  • 2
  • +3
10 Comments
 
LVL 37

Expert Comment

by:TommySzalapski
ID: 39904077
You really want sizeof(my_struct)/sizeof(my_type) to get the number of items in the array.

The incomplete type error is just because the definition of my_type is probably not clear in the that file. Maybe you need to include a .h that you are missing?

It also looks like you may be confusing struct and array. Is that possible?
0
 
LVL 1

Author Comment

by:elorc
ID: 39904159
I know it's an array of the struct. I probably didn't word the original post as well as I should have. I posted it somewhat hurriedly.

The struct my_type is defined in a header file that is included in all of the C files in the project. That's why I'm confused as to what it's complaining about. This code is about 20-something years old and has run through a lot of different hands, but basically the header file has the main struct itself defined:

struct my_type
{
   ...
};

Open in new window


Then, in tables.c is the code from the original post. That contains a bunch of hard-coded entries.

The goal is to rewrite pretty much all of this when time permits, but for now I've just been going through cleaning up some things where possible. I changed the line to sizeof(my_struct)/sizeof(my_type), and it complains about my_type in addition to the original error:

error: 'my_type' undeclared (first use in this function)

Like I said though, the header file where my_type is defined is definitely included. Is it a problem with the way my_type is defined in the header file? I'm sure the issue is a combination of something I'm screwing up, along with the messiness and lack of clarity in the code.
0
 
LVL 37

Assisted Solution

by:TommySzalapski
TommySzalapski earned 400 total points
ID: 39904341
Right. It's c not c++ you need sizeof(struct my_struct) there.
This code works perfectly for me (in c).

#include <stdio.h>

struct my_type
{
  int x;
};

int main()
{
  struct my_type my_array[] = {{4}, {6}};

  printf("%u -- %u\n", sizeof(my_array), sizeof(my_array)/sizeof(struct my_type));

  return 0;
}

Open in new window

It prints 8 -- 2 which is what I expected. Check how you declare the array perhaps?
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 12

Expert Comment

by:satsumo
ID: 39905120
Does the hard coded maximum cause a problem?
0
 
LVL 37

Expert Comment

by:TommySzalapski
ID: 39905156
I think you were just missing the =
const struct my_type my_struct[] = {
    ...
};

Open in new window

0
 
LVL 9

Expert Comment

by:Subrat (C++ windows/Linux)
ID: 39905356
As already discussed you are not instantiating the structure.
Ex:
int 5;//Not meaningful.
int x = 5;//Perfectly valid.here x is a variable of int type.
Likely we have to declarethe structuere variable as follows.
struct my_type myStruct.// Now use myStruct when needed.
0
 
LVL 32

Expert Comment

by:phoffric
ID: 39905375
>> int x = 5;//Perfectly valid.here x is a variable of int type.
-- not valid in a c-struct.

>> struct my_type myStruct.// Now use myStruct when needed.
-- The author is asking for an array of structs.
0
 
LVL 35

Accepted Solution

by:
sarabande earned 1600 total points
ID: 39905952
when the array my_struct is defined in tables.c but used in process.c an 'extern' declaration of the my_struct is necessary either in process.c or in a header.

if the extern declaration is like

extern const struct my_type my_struct[];

Open in new window


the size of the array cannot be deduced in process.c but only in tables.c.

when i compile  a 2nd source with the extern declaration  and sizeof(my_struct), the ansi c compiler of visual c gives 'warning C4034: sizeof returns 0' what may be equivalent to the error posted.

to go around that error you could determine the number of array elements and change the extern statement to declare a fixed-sized array.  or, you use a further global variable which takes the array size in tables.c like

const struct my_type my_struct[] {
    ...
}; 
const size_t my_struct_nitems = sizeof(my_struct)/sizeof(my_struct[0]);

Open in new window


then the my_struct_nitems also could be used in process.c if you add an extern declaration there.

Sara
0
 
LVL 1

Author Closing Comment

by:elorc
ID: 39906127
Thanks, everyone, for your assistance on this. Sara: Your recommendation ended up being the working solution.

It's not really a huge deal that the number was hard-coded, but in the event that this code needs to be maintained longer than expected, I'm trying to find things I can do to improve its maintainability slightly. This allows me to reduce the number of manual changes that need to be made when updating content already hard-coded into the program. I'm going to apply this solution to a few similar parts of the program.
0
 
LVL 35

Expert Comment

by:sarabande
ID: 39906578
normally as a better way than to using global shared variables you might think of a function which provides items from static array:

// tables.c
...
const struct my_type * get_my_type_at(int idx)
{
   static const struct my_type my_struct[] {
    ...
    }; 
   static const size_t my_struct_nitems = sizeof(my_struct)/sizeof(my_struct[0]); 
   if (idx >= 0 && idx < (int)my_struct_nitems)
   {
          return &my_struct[idx];
   }
   return 0;
} 

Open in new window




for (i = 1; sizeof(my_struct); i++) {
you should be aware that in c the index is zero-based. for loops would start with 0 and look like

for (size_t n = 0; n < my_struct_nitems; ++n)
{
    ... 

Open in new window


Sara
0

Featured Post

Enroll in August's Course of the Month

August's CompTIA IT Fundamentals course includes 19 hours of basic computer principle modules and prepares you for the certification exam. It's free for Premium Members, Team Accounts, and Qualified Experts!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Q&A with Course Creator, Mark Lassoff, on the importance of HTML5 in the career of a modern-day developer.
The SignAloud Glove is capable of translating American Sign Language signs into text and audio.
Simple Linear Regression
Starting up a Project

765 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question