0

I have the following code in C:

Two sturct:

typedef struct
{
  int age;
  int phone; 
} Student;

typedef struct
{ 
  int classNum;
  Student student[1]; 
} ClassRoom;

And then I created memory for 10 students:

ClassRoom * classRoom =  (ClassRoom*)malloc(sizeof(ClassRoom) + sizeof(Student) * 9);

Then I try to loop through all the students:

int i = 0;
for(i = 0; i < 10; i++)
{
   classRoom->student[i].age = 20;
   classRoom->student[i].phone = 20;  
}

Then I got a lint warning:

Warning 662: Possible creation of out-of-bounds pointerby operator '[

Looks like it says this two lines has lint warnings:

classRoom->student[i].age = 20;
classRoom->student[i].phone = 20;

What is the problem and how to fix it? I can not change the struct of ClassRoom, and are there any way to solve it?

ratzip
  • 113
  • 2
  • 11
  • there are sizeof(ClassRoom) in the malloc – ratzip Mar 21 '14 at 17:24
  • http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf See 6.7.2.1 – Aean Mar 21 '14 at 17:26
  • if you want a variable length array at the end of a struct, it needs to be declared with empty brackets, not a size – Steve Cox Mar 21 '14 at 17:26
  • @SteveCox: there is already room for one student in str Classroom structure, therefore ho only allocates for 9 student more as he want apparently 10 students. All this look correct to me. – Jabberwocky Mar 21 '14 at 17:28
  • @SteveCox: with some compilers you cannot declare an array with empty brackets. – Jabberwocky Mar 21 '14 at 17:29
  • yes you can, that has been in the standard since k&r c – Steve Cox Mar 21 '14 at 17:29
  • 1
    if you literally cannot change the struct, there's no way to resolve the lint issue. just ignore it – Steve Cox Mar 21 '14 at 17:31
  • @SteveCox: not so sure about this, my old VC6 compiler show following warning when I use a zero sized array: `warning C4200: nonstandard extension used : zero-sized array in struct/union`. – Jabberwocky Mar 21 '14 at 17:31
  • that error should show up if you declare Student student[0];. Student student[] is standard compliant (see example 17 in the above linked standard) – Steve Cox Mar 21 '14 at 17:32
  • @SteveCox: using [0] or [1] yields exactly the same warning with both VS6 and VS2012 compilers. BTW it's a warning, not an error. – Jabberwocky Mar 21 '14 at 17:41
  • @MichaelWalz I know it does, I just said it does. You're not supposed to use either of those. – Steve Cox Mar 21 '14 at 17:42
  • @SteveCox: sorry, I meant "[0] or []" not "[0] or [1]" in my previous comment. – Jabberwocky Mar 21 '14 at 17:43
  • @MichaelWalz then VS isn't standard compliant and should be ignored in this case, since the question is tagged with C. (did you make sure it was the last element in the struct?) – Steve Cox Mar 21 '14 at 17:44
  • @SteveCox: following links pretend the contrary : [Link1](http://stackoverflow.com/questions/9722632/what-happens-if-i-define-a-0-size-array-in-c-c), [Link2](http://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html). So in C90 it was not standard but in C99 it is standard. – Jabberwocky Mar 21 '14 at 17:52
  • @MichaelWalz What C99 6.7.2.1 §16 said is "**As a special case**, the last element of a structure with more than one named member may have an incomplete array type; this is called a flexible array member." – Aean Mar 21 '14 at 17:59
  • Any ways can work around it? – ratzip Mar 23 '14 at 21:27

3 Answers3

0

You are accessing unallocated memory in your for loop.

You can do this as

int i = 0;
for(i = 0; i < 10; i++)
{
   classRoom[i].student[1].age = 20;
   classRoom[i].student[1].phone = 20;  
}
haccks
  • 104,019
  • 25
  • 176
  • 264
0
for(i = 0; i < 10; i++)
{
   classRoom->student[i].age = 20;
   classRoom->student[i].phone = 20;  
}

here you are using 10 objects but you allcated memory for only 9 objects. that is one thing to be noted.

ClassRoom * classRoom =  (ClassRoom*)malloc(sizeof(ClassRoom) + sizeof(Student) * 9);

this allcates memory for only 9 students so change it to

ClassRoom * classRoom =  (ClassRoom*)malloc(sizeof(ClassRoom) + sizeof(Student) * 10);

if you can change structure then can use, for variable number of students craete

typedef struct
{ 
  int classNum;
  Student *student; 
} ClassRoom;

then allocate student[] a memory dynamically depending on number of students. treat student as a array with memory allocated dynamically

LearningC
  • 3,182
  • 1
  • 12
  • 19
0

Well, you are trying to dereference unallocated memory using the Student[i] as the structure Classroom has only 1 Student elements inside it. you should just allocate enough memory to hold 5 Classroom struct and then loop through the Classroom structures using Classroom[i]->Student

Ankit Kumar
  • 1,433
  • 1
  • 16
  • 24