Как очистить предупреждение о ворсе в C?

У меня есть следующий код на C:

Две структуры:

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

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

А затем я создал память для 10 учеников:

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

Затем я пытаюсь перебрать всех студентов:

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

Затем я получил предупреждение о ворсе:

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

Похоже, в этих двух строках есть предупреждения:

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

В чем проблема и как ее исправить? Я не могу изменить структуру ClassRoom, и есть ли способ решить эту проблему?


person ratzip    schedule 21.03.2014    source источник
comment
в malloc есть sizeof(ClassRoom)   -  person ratzip    schedule 21.03.2014
comment
open-std.org/jtc1/sc22/wg14/ www/docs/n1256.pdf См. 6.7.2.1   -  person Aean    schedule 21.03.2014
comment
если вам нужен массив переменной длины в конце структуры, его нужно объявить с пустыми скобками, а не размером   -  person Steve Cox    schedule 21.03.2014
comment
@SteveCox: в структуре класса str уже есть место для одного ученика, поэтому он выделяет еще только для 9 учеников, поскольку ему, по-видимому, нужно 10 учеников. Все это выглядит правильно для меня.   -  person Jabberwocky    schedule 21.03.2014
comment
@SteveCox: с некоторыми компиляторами вы не можете объявить массив с пустыми скобками.   -  person Jabberwocky    schedule 21.03.2014
comment
да, вы можете, это было в стандарте с тех пор, как k&r c   -  person Steve Cox    schedule 21.03.2014
comment
если вы буквально не можете изменить структуру, нет никакого способа решить проблему с ворсом. просто игнорируй это   -  person Steve Cox    schedule 21.03.2014
comment
@SteveCox: не уверен в этом, мой старый компилятор VC6 показывает следующее предупреждение, когда я использую массив нулевого размера: warning C4200: nonstandard extension used : zero-sized array in struct/union.   -  person Jabberwocky    schedule 21.03.2014
comment
эта ошибка должна появиться, если вы объявите Student student[0];. Student student[] соответствует стандарту (см. пример 17 в приведенном выше стандарте)   -  person Steve Cox    schedule 21.03.2014
comment
@SteveCox: использование [0] или [1] дает одно и то же предупреждение как для компиляторов VS6, так и для VS2012. Кстати, это предупреждение, а не ошибка.   -  person Jabberwocky    schedule 21.03.2014
comment
@MichaelWalz Я знаю, что да, я просто сказал, что да. Вы не должны использовать ни один из них.   -  person Steve Cox    schedule 21.03.2014
comment
@SteveCox: извините, я имел в виду [0] или [], а не [0] или [1] в моем предыдущем комментарии.   -  person Jabberwocky    schedule 21.03.2014
comment
@MichaelWalz, тогда VS не соответствует стандарту и в этом случае его следует игнорировать, поскольку вопрос помечен буквой C. (Вы убедились, что это был последний элемент в структуре?)   -  person Steve Cox    schedule 21.03.2014
comment
@SteveCox: следующие ссылки говорят об обратном: Link1, Ссылка2. Так вот в С90 это не было стандартом, а в С99 это стандарт.   -  person Jabberwocky    schedule 21.03.2014
comment
@MichaelWalz Что C99 6.7.2.1 §16 сказал, В качестве особого случая последний элемент структуры с более чем одним именованным членом может иметь тип неполного массива; это называется гибким членом массива.   -  person Aean    schedule 21.03.2014
comment
Любые способы могут обойти это?   -  person ratzip    schedule 24.03.2014


Ответы (3)


Вы обращаетесь к нераспределенной памяти в цикле for.

Вы можете сделать это как

int i = 0;
for(i = 0; i < 10; i++)
{
   classRoom[i].student[1].age = 20;
   classRoom[i].student[1].phone = 20;  
}
person haccks    schedule 21.03.2014
comment
это не то, чего он хочет. он хочет переменное количество студентов в структуре - person Steve Cox; 21.03.2014
comment
это то же самое, но я не могу ничего изменить в структуре - person ratzip; 21.03.2014

Ну, вы пытаетесь разыменовать нераспределенную память, используя Student[i], поскольку structure Classroom содержит только 1 Student элементов внутри. вы должны просто выделить достаточно памяти для хранения 5 Classroom struct, а затем перебрать структуры Classroom, используя Classroom[i]->Student

person Ankit Kumar    schedule 21.03.2014
comment
Памяти на десять Студенческих выделено - person ratzip; 24.03.2014

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

здесь вы используете 10 объектов, но выделили память только для 9 объектов. это одна вещь, которую следует отметить.

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

это выделяет память только для 9 студентов, поэтому измените его на

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

если вы можете изменить структуру, то можете использовать для создания переменного количества студентов

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

затем динамически распределяйте память студента [] в зависимости от количества студентов. относиться к студенту как к массиву с динамически выделенной памятью

person LearningC    schedule 21.03.2014
comment
Здравствуйте, структуру ClassRoom нельзя изменить. Я не могу это изменить. - person ratzip; 21.03.2014
comment
@ratzip хорошо. вы уточнили это в вопросе? и вы хотите использовать student[1] массив размера 1? - person LearningC; 21.03.2014
comment
@ratzip хорошо. проверьте, что вы выделили память только для 9 студентов, но доступ к 10 - person LearningC; 21.03.2014