1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 |
#include<iostream> #include<iomanip> #include<fstream> #include<string> using namespace std; struct data{ char fam[10]; int m[3]; }; struct student{ data d; student *next; }; student *st = 0, *en = 0; void view() { system("cls"); if (!st){ cout << "+------------------------------------------------+" << endl; cout << "| Ничего нет! |" << endl; cout << "+------------------------------------------------+" << endl; cin.get(); cin.get(); return; } student *tmp = st; int i = 0; cout << "+------------------------------------------------+n"; cout << "| | | Оценки |n"; cout << "| № | Фамилия |-----------------------------|n"; cout << "| | студента |Физика |История |Информатика |n"; cout << "+------------------------------------------------+n"; while (tmp) { printf("|%2d | %-12s |%6d |%7d |%11d |n", ++i, tmp->d.fam, tmp->d.m[0], tmp->d.m[1], tmp->d.m[2]); tmp = tmp->next; } cout << "+------------------------------------------------+n"; cout << "Для выхода нажмите Enter" << endl; cin.get(); cin.get(); return; } student scan(){ student el; cout << "Фамилия: "; cin >> el.d.fam; if (el.d.fam[0] == '*') return el; cout << "Оценки (3): "; cin >> el.d.m[0] >> el.d.m[1] >> el.d.m[2]; el.next = NULL; return el; } void addnew(student el) { if (el.d.fam[0] != '*') { if (!st) { st = new student; *st = el; st->next = NULL; en = st; } else { student *tmp, *tmp2, *tmp3; tmp = st; tmp3 = new student; *tmp3 = el; int flag = 0; while (strcmp(tmp->d.fam, (el.d.fam)) < 0) { tmp2 = tmp; tmp = tmp->next; flag = 1; if (!tmp) break; } if (!flag) { tmp3->next = tmp; st = tmp3; } else if (!tmp){ tmp2->next = tmp3; en = tmp3; } else{ tmp2->next = tmp3; tmp3->next = tmp; } } } } void delall(){ student *temp; if (st == NULL) return; while (1) { temp = st; st = st->next; delete temp; if (st == NULL) break; } en = NULL; cout << "Список очищен" << endl; cin.get(); cin.get(); return; } void create(){ student el; cout << "Для выхода нажмите * в поле фамилии" << endl; while (1) { el = scan(); if (el.d.fam[0] != '*') addnew(el); else break; } return; } void keysearch(){ student *tmp; char n[10]; int count = 0, found = 0; tmp = st; cout << "Введите фамилию для поиска" << endl; cin >> n; system("cls"); cout << "+------------------------------------------------+" << endl; cout << "| Поиск элементов | " << endl; cout << "+------------------------------------------------+n"; cout << "| | | Оценки |n"; cout << "| № | Фамилия |-----------------------------|n"; cout << "| | студента |Физика |История |Информатика |n"; cout << "+------------------------------------------------+n"; while (tmp) { count++; if (strcmp(tmp->d.fam, n) == 0) { found = 1; printf("|%2d | %-12s |%6d |%7d |%11d |n", count, tmp->d.fam, tmp->d.m[0], tmp->d.m[1], tmp->d.m[2]); cout << "+------------------------------------------------+" << endl; } tmp = tmp->next; } if (!found) { cout << "| Введенного элемента нет в списке |" << endl; cout << "+------------------------------------------------+" << endl; } cin.get(); cin.get(); } void deletet(){ student *tmp, *tmp2; int n, i = 0, flag = 0; tmp = st; cout << "Введите номер удаляемого элемента" << endl; cin >> n; if (n == 1){ tmp2 = tmp->next; st = tmp2; delete tmp; } else { while (tmp) { ++i; if (i == (n - 1)) { tmp2 = tmp->next; tmp->next = tmp->next->next; delete tmp2; flag = 1; break; } tmp = tmp->next; } if (flag) cout << "Элемент удален" << endl; else cout << "Нет элемента с таким номером" << endl; cin.get(); cin.get(); } } int read() { int a, i = 0; student el; ifstream fin("1.txt", ios::binary | ios::in); if (!fin) return -1; else { cout << "Удалить существующие элементы? Да=1" << endl; cin >> a; if (a == 1) delall(); fin.seekg(0, ios::beg); while (fin.read((char*)&(el.d), sizeof data)) { el.next = NULL; addnew(el); i++; } } fin.close(); return i; } void save(){ student *tmp = st; ofstream fout("1.txt", ios::out | ios::trunc); if (!fout) { cout << "Не могу открыть файл для записи" << endl; cin.get(); cin.get(); return; } else { while (tmp) { fout.write((char*)&tmp->d, sizeof data); tmp = tmp->next; } fout.close(); } return; } int main() { setlocale(0, "rus"); char c = 0; int i = -2; while (1){ system("cls"); cout << "+-------------------------------+" << endl; cout << "| Коротков А.А. ПЗ №2 |" << endl; cout << "+-------------------------------+" << endl; if (i == -2) cout << "| Статус файла |" << endl; else if (i == -1) cout << "| Не могу открыть файл |" << endl; else cout << "| Считано " << setw(3) << i << " записей |" << endl; cout << "+-------------------------------+" << endl; cout << "| Меню |" << endl; cout << "+-------------------------------+" << endl; cout << "|1-Организация нового списка |" << endl; cout << "|2-Добавление элемента |" << endl; cout << "|3-Поиск элементата по фамилии |" << endl; cout << "|4-Удаление элементата по номеру|" << endl; cout << "|5-Просмотр списка |" << endl; cout << "|6-Очистка списка |" << endl; cout << "|7-Сохранить в файл |" << endl; cout << "|8-Считать из файла |" << endl; cout << "|0-Выход |" << endl; cout << "+-------------------------------+n"; cin >> c; switch (c){ case'1': create(); break; case'2': addnew(scan()); break; case'3': keysearch(); break; case'4': deletet(); break; case'5': view(); break; case'6': delall(); break; case'7': save(); break; case'8': i = read(); break; case'0': return 0; break; default: {cout << "Вводите числа 1-8" << endl; cin.get(); cin.get(); } } } return 0; } |
Содержание
- ошибка C4703: потенциально неинициализированная переменная локального указателя ‘pNamesPtr’ используется
- 3 ответа
- /sdl (включение дополнительных проверок безопасности)
- Синтаксис
- Комментарии
- Проверки времени компиляции
- Проверки во время выполнения
- Установка данного параметра компилятора в среде разработки Visual Studio
- используется потенциально неинициализированная переменная локального указателя ‘playtimer’
- Решение
- /sdl (включение дополнительных проверок безопасности)
- Синтаксис
- Комментарии
- Проверки времени компиляции
- Проверки во время выполнения
- Установка данного параметра компилятора в среде разработки Visual Studio
- Предупреждения компилятора с C4600 по C4799
ошибка C4703: потенциально неинициализированная переменная локального указателя ‘pNamesPtr’ используется
Я работаю над проектом crypter и при попытке скомпилировать программу столкнулся с следующей ошибкой.
main.cpp(520): ошибка C4703: потенциально неинициализированный локальный указатель переменная ‘pNamesPtr’ используется
========== Build: 0 удалось, 1 не удалось, 0 обновлено, 0 пропущено ==========
Может кто-нибудь помочь мне с этой ошибкой? Вам нужен больше кода, чтобы иметь хороший ответ?
3 ответа
Это предупреждение не всегда является ошибкой, иногда просто результатом оптимизации. Так как это в вашем коде, и вы не знаете, что это такое, это может быть ошибка.
Например, если я пишу:
Если вы оптимизируете, вы можете знать, что значение whatever всегда истинно, если значение this_and_that истинно, поэтому, если printf вызывается, тогда i уже гарантированно инициализируется, но компилятор часто не может определить связь между this_and_that и whatever , поэтому вы получаете предупреждение. Одним из возможных быстрых исправлений для этого предупреждения является инициализация переменной до значения по умолчанию, где вы ее объявляете. На мой взгляд, избавление от инициализации — плохая практика и источник множества ошибок.
Это означает, что
- вы не инициализируете pNamesPtr , когда вы его объявляете, поэтому он начинается с недопустимого значения; и
- компилятор не может быть уверен, что перед его использованием вам будет присвоено действительное значение.
Проверьте все пути кода от объявления до точки использования. Все ли они назначают что-то разумное для переменной? Если нет, исправьте это, чтобы они это сделали.
Если они это сделают, и вы уверены, что правильно назначили его, можете ли вы упростить код, чтобы он был очевидным для компилятора?
Если все остальное не удается, вы можете отключить компилятор, инициализируя его значением nullptr или другим значением по умолчанию в инициализации. Но делайте это только в том случае, если вы действительно уверены, что ваш код верен — компиляторы обычно хорошо разбираются в таких ошибках.
Источник
/sdl (включение дополнительных проверок безопасности)
Включает рекомендуемые проверки жизненного цикла разработки безопасности (SDL). Эти проверки изменяют предупреждения, связанные с безопасностью, на ошибки и задают дополнительные безопасные функции создания кода.
Синтаксис
Комментарии
/sdl включает надмножество базовых проверок безопасности, предоставляемых /GS и переопределяет /GS- . По умолчанию /sdl параметр отключен. /sdl- отключает дополнительные проверки безопасности.
Проверки времени компиляции
/sdl позволяет применять эти предупреждения как ошибки:
Включаемые/sdl предупреждения | Эквивалентный параметр командной строки | Описание |
---|---|---|
C4146 | /we4146 | Унарный оператор «минус» был применен к беззнаковому типу, что приведет к получению результата без знака. |
C4308 | /we4308 | Отрицательная целая константа преобразуется в беззнаковый тип, что, вероятно, приведет к получению бессмысленного результата. |
C4532 | /we4532 | continue Использование ключевых слов , break или goto в блоке __finally / finally имеет неопределенное поведение во время аномального завершения. |
C4533 | /we4533 | Код инициализации переменной не выполняется. |
C4700 | /we4700 | Используется неинициализированная локальная переменная. |
C4703 | /we4703 | Используется потенциально неинициализированная локальная переменная-указатель. |
C4789 | /we4789 | Переполнение буфера при использовании определенных функций среды выполнения C (CRT). |
C4995 | /we4995 | Использование функции, помеченной прагмой deprecated . |
C4996 | /we4996 | Использование функции, помеченной как deprecated . |
Проверки во время выполнения
Если /sdl параметр включен, компилятор создает код, который выполняет эти проверки во время выполнения:
Включает строгий режим обнаружения переполнения буфера /GS во время выполнения, эквивалентный компиляции с #pragma strict_gs_check(push, on) помощью .
Выполняет ограниченную очистку указателя. В выражениях, не связанных с разыменованиями, и в типах, не имеющих определяемого пользователем деструктора, ссылки на указатели задаются как недопустимый адрес после вызова delete метода . Эта очистка помогает предотвратить повторное использование устаревших ссылок на указатели.
Инициализирует указатели членов класса. Автоматически инициализирует члены класса типа nullptr указателя на при создании экземпляра объекта (перед запуском конструктора). Это помогает предотвратить использование неинициализированных указателей, которые конструктор явно не инициализирует. Инициализация указателя члена, созданного компилятором, вызывается при условии, что:
Объект не выделяется с помощью пользовательского (определяемого пользователем) operator new
Объект не выделяется как часть массива (например new A[x] , ).
Класс не управляется и не импортируется
Класс имеет определяемый пользователем конструктор по умолчанию.
Для инициализации с помощью созданной компилятором функции инициализации класса член должен быть указателем, а не свойством или константой.
Установка данного параметра компилятора в среде разработки Visual Studio
Откройте диалоговое окно Страницы свойств проекта. Подробнее см. в статье Настройка компилятора C++ и свойства сборки в Visual Studio.
Перейдите на страницу свойств Свойства конфигурации>C/C++>Общие.
Задайте свойство проверки SDL с помощью раскрывающегося списка свойств. Нажмите кнопку ОК или Применить , чтобы сохранить изменения.
Источник
используется потенциально неинициализированная переменная локального указателя ‘playtimer’
Не могли бы вы помочь мне с этой проблемой, пожалуйста? Заранее спасибо.
Выше приведен мой код. Ошибки и предупреждения ниже:
предупреждение C4101: ‘str’: локальная переменная без ссылки —
предупреждение C4715: «SDL_main»: не все пути управления возвращают значение —
ошибка C4703: потенциально неинициализированная переменная локального указателя
«playtimer» используется
Решение
Единственное место, которое вы инициализируете playtimer в
Это условная инициализация и средства playtimer может или не может быть инициализирован в следующем коде. Тогда у вас есть
Так что если вы достигнете SDL_RemoveTimer(playtimer); playtimer может или не может быть инициализирован из-за первого оператора if. Теперь мы можем рассуждать, что поскольку оба условия имеют одинаковое условие, то playtimer должны быть инициализированы, и мы в порядке. К сожалению, попытка заставить компилятор увидеть, что это чрезвычайно сложно и более чем вероятно, будет тем, что производители компиляторов решили не реализовывать. Также, если это многопоточная программа mode может измениться между ними, если операторы и компилятор не смогут проанализировать это.
Я предлагаю вам объединить оба оператора в один блок if, чтобы гарантировать playtimer инициализируется, когда используется:
Я бы также предложил вам сделать то же самое для simthread ,
Источник
/sdl (включение дополнительных проверок безопасности)
Включает рекомендуемые проверки жизненного цикла разработки безопасности (SDL). Эти проверки изменяют предупреждения, связанные с безопасностью, на ошибки и задают дополнительные безопасные функции создания кода.
Синтаксис
Комментарии
/sdl включает надмножество базовых проверок безопасности, предоставляемых /GS и переопределяет /GS- . По умолчанию /sdl параметр отключен. /sdl- отключает дополнительные проверки безопасности.
Проверки времени компиляции
/sdl позволяет применять эти предупреждения как ошибки:
Включаемые/sdl предупреждения | Эквивалентный параметр командной строки | Описание |
---|---|---|
C4146 | /we4146 | Унарный оператор «минус» был применен к беззнаковому типу, что приведет к получению результата без знака. |
C4308 | /we4308 | Отрицательная целая константа преобразуется в беззнаковый тип, что, вероятно, приведет к получению бессмысленного результата. |
C4532 | /we4532 | continue Использование ключевых слов , break или goto в блоке __finally / finally имеет неопределенное поведение во время аномального завершения. |
C4533 | /we4533 | Код инициализации переменной не выполняется. |
C4700 | /we4700 | Используется неинициализированная локальная переменная. |
C4703 | /we4703 | Используется потенциально неинициализированная локальная переменная-указатель. |
C4789 | /we4789 | Переполнение буфера при использовании определенных функций среды выполнения C (CRT). |
C4995 | /we4995 | Использование функции, помеченной прагмой deprecated . |
C4996 | /we4996 | Использование функции, помеченной как deprecated . |
Проверки во время выполнения
Если /sdl параметр включен, компилятор создает код, который выполняет эти проверки во время выполнения:
Включает строгий режим обнаружения переполнения буфера /GS во время выполнения, эквивалентный компиляции с #pragma strict_gs_check(push, on) помощью .
Выполняет ограниченную очистку указателя. В выражениях, не связанных с разыменованиями, и в типах, не имеющих определяемого пользователем деструктора, ссылки на указатели задаются как недопустимый адрес после вызова delete метода . Эта очистка помогает предотвратить повторное использование устаревших ссылок на указатели.
Инициализирует указатели членов класса. Автоматически инициализирует члены класса типа nullptr указателя на при создании экземпляра объекта (перед запуском конструктора). Это помогает предотвратить использование неинициализированных указателей, которые конструктор явно не инициализирует. Инициализация указателя члена, созданного компилятором, вызывается при условии, что:
Объект не выделяется с помощью пользовательского (определяемого пользователем) operator new
Объект не выделяется как часть массива (например new A[x] , ).
Класс не управляется и не импортируется
Класс имеет определяемый пользователем конструктор по умолчанию.
Для инициализации с помощью созданной компилятором функции инициализации класса член должен быть указателем, а не свойством или константой.
Установка данного параметра компилятора в среде разработки Visual Studio
Откройте диалоговое окно Страницы свойств проекта. Подробнее см. в статье Настройка компилятора C++ и свойства сборки в Visual Studio.
Перейдите на страницу свойств Свойства конфигурации>C/C++>Общие.
Задайте свойство проверки SDL с помощью раскрывающегося списка свойств. Нажмите кнопку ОК или Применить , чтобы сохранить изменения.
Источник
Предупреждения компилятора с C4600 по C4799
В статьях в этом разделе документации объясняется подмножество предупреждающих сообщений, создаваемых компилятором.
Компиляторы и средства сборки Visual Studio могут сообщать о различных типах ошибок и предупреждений. После обнаружения ошибки или предупреждения средства сборки могут делать предположения о намерении кода и пытаться продолжить работу, чтобы одновременно можно было сообщить о дополнительных проблемах. Если средства делают неверное предположение, последующие ошибки или предупреждения не могут применяться к проекту. При устранении проблем в проекте всегда начинайте с первой зарегистрированной ошибки (или предупреждения) и выполняйте повторную сборку как можно чаще. Одно исправление может привести к устранению многих последующих ошибок.
Чтобы получить справку по определенному диагностическом сообщению в Visual Studio, выберите его в окне Вывод и нажмите клавишу F1 . Visual Studio открывает страницу документации по этой ошибке, если она существует. Вы также можете использовать средство поиска в верхней части страницы, чтобы найти статьи о конкретных ошибках или предупреждениях. Или просмотрите список ошибок и предупреждений по инструменту и введите в оглавление на этой странице.
Не все ошибки или предупреждения Visual Studio задокументированы. Во многих случаях в диагностическом сообщении содержатся все доступные сведения. Если вы попали на эту страницу при использовании F1 и считаете, что сообщение об ошибке или предупреждении нуждается в дополнительных объяснениях, сообщите нам об этом. Вы можете использовать кнопки обратной связи на этой странице, чтобы вызвать проблему с документацией на GitHub. Если вы считаете ошибку или предупреждение неправильным или обнаружили другую проблему с набором инструментов, сообщите о проблеме с продуктом на сайте Сообщество разработчиков. Вы также можете отправлять отзывы и вводить ошибки в интегрированной среде разработки. В Visual Studio перейдите в строку меню и выберите Справка > Отправить отзыв > Сообщить о проблеме или отправьте предложение с помощью команды Отправить > отзыв > Отправить предложение.
Дополнительную помощь по ошибкам и предупреждениям можно найти на форумах Microsoft Learn Q&A . Или найдите номер ошибки или предупреждения на сайте visual Studio C++ Сообщество разработчиков. Вы также можете выполнить поиск в Stack Overflow , чтобы найти решения.
Ссылки на дополнительные справочные материалы и ресурсы сообщества см. в справке и сообществе Visual C++.
Источник
I’m working on a crypter project and ran into the following error when attempting to compile the program.
main.cpp(520): error C4703: potentially uninitialized local pointer
variable ‘pNamesPtr’ used
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
DLLNAMES[i].UsedAlready = 0;
}
*dwOutSize = (DWORD)pNamesPtr - (DWORD)pBuffer;//*<----is line 520 of error
*dwImportsSize = *dwOutSize - *dwIATSize;
return pBuffer;
}
#pragma pack(1)
typedef struct
Can someone help me with this error? Do you need more code in order to have a good answer?
SSpoke
5,5929 gold badges71 silver badges120 bronze badges
asked Feb 27, 2014 at 5:02
2
This warning isn’t always a bug, sometimes its just the result of an optimization. Since it is in your code and you don’t know what is this it might actually be a bug.
For example if I write:
int i;
if (this_and_that)
i = 5;
if (whatever)
printf("%dn", i); // <--- this may give a potential blahblah warning
If you are optimizing then you may know that the value of whatever
is always true when the value of this_and_that
is true so if printf
gets called then i
is already guaranteed to be initialized but the compiler often can not figure out the relation between this_and_that
and whatever
, this is why you get the warning. One possible quick fix to this warning is initializing the variable to a default value right where you declare it. In my opinion sparing with initialization is a bad practice and a source of a lot of bugs.
answered Feb 27, 2014 at 5:11
pasztorpistipasztorpisti
3,6291 gold badge16 silver badges24 bronze badges
3
It means that
- you don’t initialise
pNamesPtr
when you declare it, so it starts with an invalid value; and - the compiler can’t be sure that you will have assigned a valid value to it before using it.
Check all the code paths from the declaration to the point of use. Do they all assign something sensible to the variable? If not, fix it so they do.
If they do, and you’re convinced that you’re assigning it correctly, could you simplify the code so that it’s obvious to the compiler that it is?
If all else fails, then you could silence the compiler by initialising it to nullptr
or some other default value in the initialisation. But only do that if you’re really sure your code is correct — compilers are usually good at spotting mistakes like this.
answered Feb 27, 2014 at 5:08
Mike SeymourMike Seymour
247k28 gold badges442 silver badges638 bronze badges
Put this in your code:
xtype *pNamesPtr = NULL
Benjamin W.
43k16 gold badges104 silver badges113 bronze badges
answered Feb 15, 2016 at 8:55
1
- Remove From My Forums
-
Question
-
I am building mesa 8.0.4 on Windows 8 with VS2012 express and have a couple of compiler errors. One type of them is
error C4703, potentially uninitialized local pointer variable ‘iter’ used
This error occurs at line 6916 of ${MESASRC}srcglusgilibutilmipmap.c. The variable iter is declared as
const GLubyte *iter;
I can fix this error by initializing this variable like
const GLubyte *iter=NULL;
I wonder why the C++ compiler in VS2012 is so critical? It might be a warning instead of an error.
Answers
-
The recommended practice is to leave the warnings on and to fix the code rather than to ignore or suppress the warnings.
C4703 is a warning, not an error. The
SDL Checks option tells the compiler to treat warnings associated with security issues as errors. You can treat all warnings as errors with the
/WX flag.These checks make it easier to write good code: they allow the compiler to help detect problems that you don’t want to leave in your code. SDL requires the 4700 series warnings be fixed because uninitialized pointers can lead to security errors. See the
SDL Process docs,Appendix E.
If you turn this off then you will need to go to extra effort to confirm that your code is correct since the compiler won’t be helping find likely errors. If you are depending on legacy code which you can’t reasonably fix, and if you have validated that
the actual usage is safe then you can disable individual warnings with the
/wd compiler flag.By far the best course would be to fix the code not to generate the warning rather than suppressing or ignoring the warning.
—Rob
-
Marked as answer by
Monday, August 27, 2012 9:33 AM
-
Marked as answer by