Как исправить предупреждение C4700 в C ++ с помощью неинициализированных указателей?

0

Я прочитал многие предыдущие сообщения на C4700, но я не могу найти решение моей проблемы.

У меня есть небольшой скрипт, написанный для демонстрации указателей на структуру:

struct foo
{
    int * bar;
};

#include<iostream>
using namespace std;
int main()
{
    foo * fooptr;
    int * num;
    *num = 25;
    *fooptr->bar = *num;
    cout << "now fooptr points to a foo struct whose bar points to: " << *fooptr->bar;

    fooptr->bar = num;
    cout <<"now fooptr struct bar shares memory address with num at " <<num;

    return 0;
}

Когда я его компилирую, я получаю два предупреждения C4700 для неинициализированных локальных переменных num и fooptr. Я пошел вперед и инициализировал оба значения до NULL, поэтому ошибка компилятора исчезла, но не удивительно, что я получил исключение:

Необработанное исключение в 0x00265DF7 в файле test.exe: 0xC0000005: место записи нарушения доступа 0x00000000.

Видите ли, я всегда думал, что, когда я не инициализирую эти указатели, они будут автоматически инициализированы случайными адресами (так же, как неинициализированные ints/chars/doubles будут назначены мусора) --so не так ли будет здесь?

Если инициализация в этом случае действительно необходима (почему?), То есть ли простой способ решения этой проблемы?

  • 0
    Я рекомендую прочитать книгу: stackoverflow.com/questions/388242/…
  • 0
    Я прочитал и начал работать с C ++, но думаю, одной книги недостаточно :(
Показать ещё 5 комментариев
Теги:
visual-studio
pointers
struct
warnings

3 ответа

2
Лучший ответ

Неинициализированные переменные не инициализируются случайными значениями, они не инициализируются. На уровне машинного кода они имеют любое значение, когда они были созданы. Это может быть или не быть адресом фактического объекта. В любом случае, это неопределенное поведение, чтобы попытаться получить доступ к неинициализированному значению указателя, как если бы был объект по этому адресу.

Таким образом, ваш компилятор делает вам одолжение, выдавая предупреждение (это не требуется), потому что ваш код имеет неопределенное поведение.

то есть ли легкое обходное решение этой проблемы?

Установите свои указатели для указания на действительные объекты перед их разыменованием. Если вы этого не сделаете, тогда нет никаких обещаний о том, какое поведение будет иметь ваша программа.

  • 0
    Спасибо Бен, это было полезно. Я думаю, что я все еще не понимаю, когда автоматически создаются «новые» объекты, в отличие от ситуаций, когда мне приходится создавать их вручную. Чтобы решить эту проблему, я инициализировал fooptr и динамически num: foo * fooptr = new foo; int * num = new int; Кажется, все работает нормально, но когда я добираюсь до строки 13, присваивание, * fooptr-> bar = * num, я получаю «Необработанное исключение в 0x00AD5E1E в testing.exe: 0xC0000005: Место записи нарушения доступа 0xCDCDCDCD». Я пытался "* (fooptr-> bar) = * num" и "* fooptr-> bar = 25", но продолжал получать ту же ошибку. Что пошло не так?
  • 0
    @YiboYang: Когда вы говорите *fooptr->bar , вы ссылаетесь на bar . То есть вы пытаетесь получить int, на который указывает bar . Но bar ничего не указывает, потому что вы никогда не инициализировали его. Вам нужно что-то вроде этого: fooptr->bar = new int; , После этого вы можете делать любые из перечисленных вами вещей.
2

Вместо

int *num; // num points to somewhere random
*num = 25; // writing somewhere random makes zero sense
           // and if your OS allowed you to do it, you would
           // crash your computer very often.

вы должны написать

int num = 25;
int *pnum = &num; // pnum is a pointer to int which has been
                  // initialized with the address of num

И то же самое относится к содержимому struct.

1

C4700 не является ошибкой. DOT. Но MSVC не скомпилируется на C4700, что является ошибкой, потому что переключатель компилятора "/sdl" включен по умолчанию для C4700 на сайте visualstudio, переключатель MSDN/sdl для vs 2012+

Ещё вопросы

Сообщество Overcoder
Наверх
Меню