ПроблемаЭта проблема происходит, когда вы делаете следующее в последовательности:
Перераспределите память объекту с типом, который отличается от исходного выделения.
Например, в этом фрагменте кода, память, первоначально выделенная указателю с типом struct A*
перераспределен к указателю с типом struct B*
:
struct A;
struct B;
struct A *Aptr = (struct A*) malloc(sizeof(struct A));
struct B *Bptr = (struct B*) realloc(Aptr, sizeof(struct B));
Читайте из этой перераспределенной памяти, не повторно инициализируя память сначала.
Доступ для чтения на указателе на перераспределенную память может произойти через указатель, разыменовывают или индексация массива. Передача указателя на функцию, которая берет указатель на const
- квалифицированный объект как соответствующий параметр также рассчитывает как доступ для чтения.
РискЧтение из перераспределенной памяти, которая не была повторно инициализирована, является неопределенным поведением.
ИсправлениеПовторно инициализируйте память после перераспределения и перед первым доступом для чтения.
Средство проверки рассматривает любой доступ для записи на указателе на перераспределенную память как удовлетворение требованию реинициализации (даже если объектная сила только быть частично повторно инициализированным). Доступ для записи на указателе на перераспределенную память может произойти через указатель, разыменовывают или индексация массива. Передача указателя на функцию, которая берет указатель на non-const
- квалифицированный объект как соответствующий параметр также рассчитывает как доступ для записи.
Пример – несовместимый: чтение из перераспределенной памяти, не повторно инициализируя сначала#include<cstdlib>
struct group {
char *groupFirst;
int groupSize;
};
struct groupWithID {
int groupID;
char *groupFirst;
int groupSize;
};
char* readName();
int readSize();
void createGroup(int nextAvailableID) {
struct group *aGroup;
struct groupWithID *aGroupWithID;
aGroup = (struct group*) malloc(sizeof(struct group));
aGroup->groupFirst = readName();
aGroup->groupSize = readSize();
if(!aGroup) {
/*Handle error*/
}
/* Reassign to group with ID */
aGroupWithID = (struct groupWithID*) realloc(aGroup, sizeof(struct groupWithID));
if(!aGroupWithID) {
free(aGroup);
/*Handle error*/
}
if(aGroupWithID -> groupSize > 0) { /* Noncompliant */
/* ... */
}
/* ...*/
free(aGroupWithID);
}
В этом примере, память, выделенная group*
указатель с помощью malloc
функция перераспределена к groupWithID*
указатель с помощью realloc
функция. Существует доступ для чтения на перераспределенной памяти, прежде чем память будет повторно инициализирована.
Коррекция – повторно инициализирует память после перераспределения и прежде сначала чтениеПовторно инициализируйте память, присвоенную groupWithID*
указатель перед первым доступом для чтения. Все биты памяти могут быть повторно инициализированы с помощью memset
функция.
#include<cstdlib>
#include<cstring>
struct group {
char *groupFirst;
int groupSize;
};
struct groupWithID {
int groupID;
char *groupFirst;
int groupSize;
};
char* readName();
int readSize();
void createGroup(int nextAvailableID) {
struct group *aGroup;
struct groupWithID *aGroupWithID;
aGroup = (struct group*) malloc(sizeof(struct group));
aGroup->groupFirst = readName();
aGroup->groupSize = readSize();
if(!aGroup) {
/*Handle error*/
}
/* Reassign to group with ID */
aGroupWithID = (struct groupWithID*) realloc(aGroup, sizeof(struct groupWithID));
if(!aGroupWithID) {
free(aGroup);
/*Handle error*/
}
memset(aGroupWithID, 0 , sizeof(struct groupWithID));
/* Reinitialize group */
if(aGroupWithID -> groupSize > 0) {
/* ... */
}
/* ...*/
free(aGroupWithID);
}