Solved

Returning the number of items in a C struct

Posted on 2014-03-04
10
461 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
  • 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 100 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
 
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
What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

 
LVL 8

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 32

Accepted Solution

by:
sarabande earned 400 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 32

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

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Suggested Solutions

This article is meant to give a basic understanding of how to use R Sweave as a way to merge LaTeX and R code seamlessly into one presentable document.
Since upgrading to Office 2013 or higher installing the Smart Indenter addin will fail. This article will explain how to install it so it will work regardless of the Office version installed.
The goal of this video is to provide viewers with basic examples to understand and use structures in the C programming language.
The goal of this video is to provide viewers with basic examples to understand and use switch statements in the C programming language.

708 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

Need Help in Real-Time?

Connect with top rated Experts

9 Experts available now in Live!

Get 1:1 Help Now