Указатели По умолчанию инициализированное значение не равно NULL? - PullRequest
0 голосов
/ 14 января 2019

Откуда мы знаем, что указатели не инициализируются в NULL по умолчанию? Есть похожие вопросы, направленные на Почему указатели по умолчанию не инициализируются с NULL? Просто для проверки, вот очень простой код, чтобы увидеть, установлен ли указатель на NULL по умолчанию.

#include <iostream>
using namespace std;
int main()
{
    int* x;
    if(!x)
        cout << "nullptr" << endl;
    return 0;
}

и на выходе я получил сообщение nullptr. Я ценю, если кто-то может уточнить это.

Ответы [ 2 ]

0 голосов
/ 14 января 2019

Вопрос, с которым вы связались, обрабатывает переменные исключительно с локальным сроком хранения, поэтому я полагаю, что вы также обращаетесь к ним.

Такие переменные не инициализируются, если вы сами этого не делаете, поэтому они получают значение того, что было записано в их ячейке памяти ранее (стандартная формулировка: их значение равно «undeterminate») & ndash; однако ничто не говорит против того, что эта память уже равна нулю & ndash; по чистой случайности!

Вы можете попробовать следующее:

void test()
{
    int* p; // uninitialized
    std::cout << p << std::endl; // undefined behaviour!!!
    // (that's what you most likely did already...)

    // now something new: change the memory...
    p = reinterpret_cast<int*>(static_cast<uintptr_t(0xaddadaad));
}

int main()
{
    test();

    // again something new: call it a SECOND time:
    test();
}

Поскольку это неопределенное поведение, нет никаких гарантий, что вы получите какой-либо значимый вывод & ndash; Скорее всего, однако, что память первого вызова функции используется повторно во втором, и вы могли бы получить выходные данные, изменяющие порядок на следующее:

00000000
addadaad

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

0 голосов
/ 14 января 2019

Откуда мы знаем, что указатели не инициализируются в NULL по умолчанию?

Поскольку мы знаем, что стандарт говорит, что инициализированный указатель по умолчанию имеет неопределенное значение, если он имеет автоматическое или динамическое хранение. Цитата из стандарта (черновик):

[dcl.init] Если для объекта не указан инициализатор, объект инициализируется по умолчанию. Когда хранилище для объекта с автоматической или динамической продолжительностью хранения получается, объект имеет неопределенное значение , и если для объекта не выполняется инициализация, этот объект сохраняет неопределенное значение до тех пор, пока это значение заменяется ...

и далее:

[dcl.init] Инициализация по умолчанию для объекта типа T означает:

- Если T является (возможно, cv-квалифицированным) типом класса [указатель не класс, поэтому нам все равно]

- Если T является типом массива [указатель не массив, поэтому нам все равно]

- В противном случае инициализация не выполняется.


Я объявил указатель char (а также int) без инициализации и получил нулевые указатели.

Чтение неопределенного значения имеет неопределенное поведение. Цитата из стандарта (черновик):

[dcl.init] ... Если в результате оценки получено неопределенное значение, поведение не определено , за исключением следующие случаи: [случаи, которые здесь не применяются]

...