Почему input string не имеют значение NULL? - страница 3

 

Под переменную типа string выделяется память размером 12 байт, которая содержит 4 или 8 байт (в зависимости от битности системы) под указатель на строку. Если у строки нет инициализатора, то эти 12 байт по-любому заполняются нулями, независимо глобальная эта переменная или локальная. Таким образом получается неинициализированная строка (та которая ==NULL)

Это информация - служебная. Которую можно иметь в виду, но на которую нельзя закладываться.

 
Alexey Volchanskiy:


То реально под строку выделяется какая-то память при объявлении без инициализации? То есть строка - это какая-то структура/класс или просто буфер, управляемый рантаймом?

Вообще-то самое выгодное по расходу памяти было бы сделать, как в обычных массивах, по крайней мере в С++ это так.

double dArr[1024*1024*64]; // в task manager видно, что программа не распухла на 512 Мб, реально никакая память не выделена  

int _tmain(int argc, _TCHAR* argv[])
{
    dArr[0] = 1; // сразу же выделяется память 4 Кб, то есть под 512 чисел double
    return 0;
}

 И так далее, если последовательно заполнять массив, будут выделятся новые куски памяти 4 Кб. Причем память выделяет именно винда, а не код программы.

Кстати, надо и в MQL проверить, так тут или сразу выделяют..

 
Slawa:

Под переменную типа string выделяется память размером 12 байт, которая содержит 4 или 8 байт (в зависимости от битности системы) под указатель на строку. Если у строки нет инициализатора, то эти 12 байт по-любому заполняются нулями, независимо глобальная эта переменная или локальная. Таким образом получается неинициализированная строка (та которая ==NULL)

Это информация - служебная. Которую можно иметь в виду, но на которую нельзя закладываться.

Ясно, то есть все же пустой указатель выделаете. Надо массивы ваши проверить, написал постов выше.
 
Вячеслав, я не понимаю, почему встроенные строки сравниваются через одно место. Дефолтная строка должна давать истину при сравнении с "", это логично и общепринято. Проблема написать нормальный оператор==, который будет проверять указатель?
struct mql_string
{
    const char *str;
};
bool operator==(const mql_string &lhs, const mql_string &rhs)
{
#define MY_CPMNULL(L, R)             \
    if(L.str == nullptr)             \
    {                                \
        if(R.str == nullptr)         \
            return true;             \
        if(strcmp(R.str, "") == 0)   \
            return true;             \
        return false;                \
    }
    MY_CPMNULL(lhs, rhs);
    MY_CPMNULL(rhs, lhs);
    return strcmp(lhs.str, rhs.str) == 0;
#undef MYCPMNULL
}
int main()
{
    mql_string s1{nullptr}, s2{""}, s3{"sds"};
    cout << boolalpha;
    cout << "s1 == s1 " << (s1 == s1) << '\n';
    cout << "s1 == s2 " << (s1 == s2) << '\n';
    cout << "s1 == s3 " << (s1 == s3) << '\n';
    cout << "s2 == s3 " << (s2 == s3) << '\n';
}
$ ./a.out
s1 == s1 true
s1 == s2 true
s1 == s3 false
s2 == s3 false

В мкл оператор член класса, суть не меняет (ну или как у вас строки реализованы, не знаю).
 
pavlick_:
Дефолтная строка должна давать истину при сравнении с "", это логично и общепринято.

А в чем логика?

#ifdef __cplusplus
char *ch1 = 0;
char *ch2 = "";
#endif
Сравните например ch1 и ch2
 
Vladimir Karputov:
Написали когда-то, чтобы не очень огорчать любителей объвить, но не инициализировать :). Верить никому нельзя.

Насчёт инициализации и жизни глобальных переменных получен ответ из Сервисдеск. Недавно, по MQL5, а не по "бесшабашной" четвёрке.

 
Artyom Trishkin:

Насчёт инициализации и жизни глобальных переменных получен ответ из Сервисдеск. Недавно, по MQL5, а не по "бесшабашной" четвёрке.

Рассчитывать на значение или поведение "по-умолчанию" - себе дороже :). Но деньги Ваши - можете и дальше верить и объявлять переменные БЕЗ ПРИНУДИТЕЛЬНОЙ инициализации.
 
Artyom Trishkin:

Насчёт инициализации и жизни глобальных переменных получен ответ из Сервисдеск. Недавно, по MQL5, а не по "бесшабашной" четвёрке.

Артем, это вас так СД любит или другому отвечали? )))) Мне вот так не пишут, просто, спасибо за выявленную ошибку, в след. релизе исправим. А вот с глобальными переменными индикаторов надо проверить в МТ5, в четверке они сбрасывались при смене ТФ, что было для меня неприятной неожиданностью.
 
A100:

А в чем логика?

#ifdef __cplusplus
char *ch1 = 0;
char *ch2 = "";
#endif
Сравните например ch1 и ch2

А вы не видите разницы между голым указателем и классом СТРОКА? Строка не может принимать 0, такого состояния она не имеет.

Запустите:

std::string s = 0;

terminate called after throwing an instance of 'std::logic_error'
what():  basic_string::_M_construct null not valid
 
Vladimir Karputov:
Рассчитывать на значение или поведение "по-умолчанию" - себе дороже :). Но деньги Ваши - можете и дальше верить и объявлять переменные БЕЗ ПРИНУДИТЕЛЬНОЙ инициализации.

Владимир, сознайтесь как на духу - когда спать ложитесь, ставите у кровати два стакана, один с водой, а другой полный, как программист из анекдота? ))

ЗЫ: вообще, с подходом в части MQL5 согласен, нет гарантии, что в очередном билде что-то не порушат. Такое было на моей памяти. Лучше перестраховаться.