Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / Почему крашится при выходе из функции? / 25 сообщений из 30, страница 1 из 2
13.12.2016, 14:19
    #39365734
Eolt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему крашится при выходе из функции?
В чем тут баг?


Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
static  int my_addstr(HANDLE *hwnd) {
	const char* a = lib_get_string(hwnd, 0);
	const char* b = lib_get_string(hwnd, 1);
	char *str = malloc(strlen(a) + strlen(b));
	strcpy(str, a);
	strcat(str, b);
        lib_push_string(hwnd, str);
	free(str);
	return 1;
}



Ошибка

автор---------------------------
Microsoft Visual C++ Runtime Library
---------------------------
Debug Error!

HEAP CORRUPTION DETECTED: after Normal block (#62) at 0x0000024B639396F0.
CRT detected that the application wrote to memory after end of heap buffer.

(Press Retry to debug the application)

---------------------------
Прервать Повтор Пропустить
---------------------------
...
Рейтинг: 0 / 0
13.12.2016, 14:33
    #39365751
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему крашится при выходе из функции?
Под конец строки забыл место выделить
Код: plaintext
1.
char *str = malloc(strlen(a) + strlen(b) + 1);
...
Рейтинг: 0 / 0
13.12.2016, 14:34
    #39365753
Eolt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему крашится при выходе из функции?
Посмотрел лог компилятора, при сборке он выдает вот это:

автор warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.

warning C4996: 'strcat': This function or variable may be unsafe. Consider using strcat_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.


Проблема в этих функциях?
...
Рейтинг: 0 / 0
13.12.2016, 14:36
    #39365756
Eolt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему крашится при выходе из функции?
Dima TПод конец строки забыл место выделить
Код: plaintext
1.
char *str = malloc(strlen(a) + strlen(b) + 1);



Действительно! Теперь работает как надо)
...
Рейтинг: 0 / 0
13.12.2016, 14:44
    #39365766
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему крашится при выходе из функции?
EoltПосмотрел лог компилятора, при сборке он выдает вот это:

автор warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.

warning C4996: 'strcat': This function or variable may be unsafe. Consider using strcat_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.


Проблема в этих функциях?

Нет, в них ТОЖЕ ПРОБЛЕМА, но другая, и с ней ты пока ещё не столкнулся.
...
Рейтинг: 0 / 0
13.12.2016, 14:46
    #39365768
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему крашится при выходе из функции?
Код: plaintext
1.
2.
3.
4.
5.
6.
static  int my_addstr(HANDLE *hwnd) {
...
        lib_push_string(hwnd, str);
	free(str);
	return 1;
}



ещё может быть проблема (другая уже) тут, в lib_push_string передаётся строка, а потом эта строка
уничтожается.
Если lib_push_string эту строку только копирует себе, и забывает, то всё ок,
елси она сохранят ссылку на эту строку, то будут проблемы.
...
Рейтинг: 0 / 0
13.12.2016, 15:05
    #39365789
Eolt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему крашится при выходе из функции?
MasterZiv,

Как я понимаю, тип char и функции strcpy и strcat использовать не безопасно?

Надо преобразовывать строки в какой-нибудь vector<string> и работать уже с ним?
...
Рейтинг: 0 / 0
13.12.2016, 15:51
    #39365849
egorych
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему крашится при выходе из функции?
EoltКак я понимаю, тип char и функции strcpy и strcat использовать не безопасно?это такой специфик от майкрософта, объявлять стандартные функции из CRTL депрекатед. Нужно для того, чтобы нельзя было написать переносимый код, я так щитаю ))
...
Рейтинг: 0 / 0
14.12.2016, 05:27
    #39366341
Пётр Седов
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему крашится при выходе из функции?
EoltКак я понимаю, тип char ... использовать не безопасно?Тип char использовать безопасно:
Код: plaintext
1.
2.
char c = 'a';
assert(c == 'a'); // абсолютно безопасно


EoltКак я понимаю, ... функции strcpy и strcat использовать не безопасно?Тут дело даже не в безопасности, а в том, что при нормальной работе со строками, эти функции просто не нужны. Если работаем со строками в C-шном стиле, и нужна конкатенация строк, то это делается как-то так:
Код: plaintext
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.
#include <assert.h>
#include <stdarg.h>
#include <string.h>

const char* const _ns = nullptr; // null-строка, которая завершает список item-ов

char* concat(const char item_1[], ...) {
  va_list items;

  // первый проход: считаем длину результата
  size_t result_len = 0;
  va_start(items, item_1);
  for (const char* i = item_1; i != nullptr; i = va_arg(items, const char*)) {
    result_len += strlen(i);
  }
  va_end(items);

  char* result = new char[result_len + 1];

  // второй проход: копируем элементы
  size_t p = 0;
  va_start(items, item_1);
  for (const char* i = item_1; i != nullptr; i = va_arg(items, const char*)) {
    size_t l = strlen(i);
    memcpy(result + p, i, l);
    p += l;
  }
  va_end(items);

  assert(p == result_len);
  result[p] = '\0';

  return result;
}

int main() {
  char* p = concat("dir", "/", "file.bin", _ns); // не забываем '_ns' в конце списка
  assert(strcmp(p, "dir/file.bin") == 0);
  delete[] p;
  return 0;
}

без всяких strcpy/strcat. А если работаем со строками в C++-ном стиле (то есть используем std::string или его аналог), то эти функции и подавно не нужны.

EoltНадо преобразовывать строки в какой-нибудь vector<string> и работать уже с ним?В каком стиле работать со строками -- это вы уж сами решайте, они оба имеют право на жизнь. C++-ный стиль проще, потому что не надо строки вручную уничтожать.

egorychэто такой специфик от майкрософта, объявлять стандартные функции из CRTL депрекатед. Нужно для того, чтобы нельзя было написать переносимый код, я так щитаю ))Да, есть у Microsoft такая черта, тем или иным способом пытаться привязать пользователей к своим продуктам. Так называемый «vendor lock».
...
Рейтинг: 0 / 0
14.12.2016, 11:16
    #39366505
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему крашится при выходе из функции?
EoltMasterZiv,

Как я понимаю, тип char и функции strcpy и strcat использовать не безопасно?

Надо преобразовывать строки в какой-нибудь vector<string> и работать уже с ним?


нет, ты понимаешь неправильно.
это проблемы стандартной библиотеки языка С, к С++они вообще не имеют отношения.

проблемы в том, что strcpy и strcat и некоторые другие функции CRTL в принципе не могут контролировать переполнение буфера памяти, куда они пишут - у них нет соответствующего входного параметра, размера буфера.

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

это относится еще к функциям семейства sprintf , и некоторым другим.
также подобным образом решают проблемы с нереентерабельностью некоторых функций CRT типа strtok .
...
Рейтинг: 0 / 0
14.12.2016, 11:25
    #39366515
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему крашится при выходе из функции?
Пётр Седовegorychэто такой специфик от майкрософта, объявлять стандартные функции из CRTL депрекатед. Нужно для того, чтобы нельзя было написать переносимый код, я так щитаю ))Да, есть у Microsoft такая черта, тем или иным способом пытаться привязать пользователей к своим продуктам. Так называемый «vendor lock».


да ни при чем тут это, это проблема безопасности кода, и с этим борятся все производители компиляторов, в POSIX все то же самое. Я кстати потом проверю, совпадают ли MS расширения с POSIX.

Дело в том, что С и юникс делали красноглазики-хакеры, и им далеко не всегда было дело до таких проблем, как безопасность ПО, красивый и компактный код был важнее.
А уже потом все стали за головы хвататься, "Ааааа у нас же может быть переполнение! Аааа, тут же код не потокобезопасный!"

Теперь код классического cp из книги Прата , наверное, громоздок и ужасен...
...
Рейтинг: 0 / 0
14.12.2016, 13:59
    #39366743
egorych
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему крашится при выходе из функции?
MasterZivЯ кстати потом проверю, совпадают ли MS расширения с POSIX.посмотри, пожалуйста, это интересно, для общего развития.

MasterZiv в современных версиях CRTL включают новые функции, аналогичные по назначению старым, но с дополнительными параметрами, позволяющими контролировать размер выходного буфераЯ только не совсем понимаю, как этот входной параметр увеличит безопасность кода? Если я указал в нём неправильное значение, то совершенно так же будет портиться память, как и в функциях без этого параметра. Ничего оно там само контролировать не может, просто уровень совершения ошибки выдвинут чуть-чуть вперёд.
Это - неразрешимая проблема в С, и чтобы от неё избавиться, надо пользоваться С++ и соответствующими классами работы со строками.
...
Рейтинг: 0 / 0
14.12.2016, 14:24
    #39366785
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему крашится при выходе из функции?
egorychMasterZivЯ кстати потом проверю, совпадают ли MS расширения с POSIX.посмотри, пожалуйста, это интересно, для общего развития.
Например vsnprintf() вроде как C++11 а у МС ее нет, зато есть vsprintf_s()

fopen() по мнению MS опасный, поэтому в ворнингах рекомендуется использовать fopen_s()

Вобщем у МС как обычно все не как у всех.
...
Рейтинг: 0 / 0
14.12.2016, 14:35
    #39366815
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему крашится при выходе из функции?
egorychЯ только не совсем понимаю, как этот входной параметр увеличит безопасность кода? Если я указал в нём неправильное значение, то совершенно так же будет портиться память, как и в функциях без этого параметра. Ничего оно там само контролировать не может, просто уровень совершения ошибки выдвинут чуть-чуть вперёд.
Размер буфера предназначен для защиты от преднамеренных атак юзеров на переполнение буфера, а не для защиты от ошибок программиста.
И эту функцию он отлично выполняет.
...
Рейтинг: 0 / 0
14.12.2016, 14:48
    #39366845
Пётр Седов
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему крашится при выходе из функции?
MasterZivпроблемы в том, что strcpy и strcat и некоторые другие функции CRTL в принципе не могут контролировать переполнение буфера памяти, куда они пишут - у них нет соответствующего входного параметра, размера буфера.

чтобы преодолеть эти проблемы, в современных версиях CRTL включают новые функции, аналогичные по назначению старым, но с дополнительными параметрами, позволяющими контролировать размер выходного буфера.Создание аналогов старых C-шных функций с дополнительным параметром «длина буфера, в который писать результат» -- это костыльное решение. Нормальное решение -- если функция возвращает строку в качестве результата, то она и выделяет память под строку, а пользователь функции должен эту память освободить.
...
Рейтинг: 0 / 0
14.12.2016, 14:50
    #39366852
egorych
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему крашится при выходе из функции?
Anatoly MoskovskyРазмер буфера предназначен для защиты от преднамеренных атак юзеров на переполнение буфера, а не для защиты от ошибок программиста.
И эту функцию он отлично выполняет.понял, спасибо
...
Рейтинг: 0 / 0
14.12.2016, 14:55
    #39366869
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему крашится при выходе из функции?
Пётр СедовСоздание аналогов старых C-шных функций с дополнительным параметром «длина буфера, в который писать результат» -- это костыльное решение. Нормальное решение -- если функция возвращает строку в качестве результата, то она и выделяет память под строку, а пользователь функции должен эту память освободить.

Это ненормальное решение для С, да и вообще, потому что не всегда выделение памяти вообще возможно.
Представь себе архитектуру, где malloc всегда возвращает 0...
...
Рейтинг: 0 / 0
14.12.2016, 15:29
    #39366938
Пётр Седов
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему крашится при выходе из функции?
MasterZivПётр СедовСоздание аналогов старых C-шных функций с дополнительным параметром «длина буфера, в который писать результат» -- это костыльное решение. Нормальное решение -- если функция возвращает строку в качестве результата, то она и выделяет память под строку, а пользователь функции должен эту память освободить.

Это ненормальное решение для С,Ну вот например библиотека GLib написана на чистом C.
// https://developer.gnome.org/glib/stable/glib-String-Utility-Functions.html#g-strdup-printf g_strdup_printf ()
Код: plaintext
1.
2.
3.
gchar *
g_strdup_printf (const gchar *format,
                 ...);

Similar to the standard C sprintf() function but safer, since it calculates the maximum space required and allocates memory to hold the result. The returned string should be freed with g_free() when no longer needed.
...
Returns
a newly-allocated string holding the result

MasterZivда и вообще, потому что не всегда выделение памяти вообще возможно.
Представь себе архитектуру, где malloc всегда возвращает 0...Так это скорее всего какие-нибудь embedded платформы, обычные программы туда не портируют.
...
Рейтинг: 0 / 0
15.12.2016, 11:26
    #39367470
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему крашится при выходе из функции?
Пётр Седов,
кто знает что куда портируют?
ты предлагаешь туда еще и CRT всегда портировать?
...
Рейтинг: 0 / 0
15.12.2016, 13:34
    #39367662
Siemargl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему крашится при выходе из функции?
Пётр СедовMasterZivпроблемы в том, что strcpy и strcat и некоторые другие функции CRTL в принципе не могут контролировать переполнение буфера памяти, куда они пишут - у них нет соответствующего входного параметра, размера буфера.

чтобы преодолеть эти проблемы, в современных версиях CRTL включают новые функции, аналогичные по назначению старым, но с дополнительными параметрами, позволяющими контролировать размер выходного буфера.Создание аналогов старых C-шных функций с дополнительным параметром «длина буфера, в который писать результат» -- это костыльное решение. Нормальное решение -- если функция возвращает строку в качестве результата, то она и выделяет память под строку, а пользователь функции должен эту память освободить.Это долго и не всегда нужно.
...
Рейтинг: 0 / 0
15.12.2016, 16:27
    #39367939
Изопропил
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему крашится при выходе из функции?
SiemarglЭто долго и не всегда нужно.
да и не совсем ясно, из какого пула выделять
...
Рейтинг: 0 / 0
16.12.2016, 03:59
    #39368251
Пётр Седов
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему крашится при выходе из функции?
MasterZivкто знает что куда портируют?Я знаю, что серьёзные программы повсеместно используют динамическое распределение памяти, поэтому портировать их на embedded платформы без heap-а никто не будет.

MasterZivты предлагаешь туда еще и CRT всегда портировать?Я предлагаю забыть функции strcpy/strcat. А их костыльные аналоги, которые Visual C++ пытается подсунуть программисту, даже рассматривать не стоит.

SiemarglПётр Седовпропущено...
Создание аналогов старых C-шных функций с дополнительным параметром «длина буфера, в который писать результат» -- это костыльное решение. Нормальное решение -- если функция возвращает строку в качестве результата, то она и выделяет память под строку, а пользователь функции должен эту память освободить.Это долго и не всегда нужно.Ну а как тогда делать конкатенацию строк, если работаем со строками в C-шном стиле? Именно про это шла речь в первом сообщении. Размазывать по всему коду вызовы функций strcpy/strcat? Мне такой способ не нравится:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
strcpy(buf, "aaa");
strcat(buf, "bbb"); // пробегает "aaa", пишет "bbb"
strcat(buf, "ccc"); // пробегает "aaabbb", пишет "ccc"
strcat(buf, "ddd"); // пробегает "aaabbbccc", пишет "ddd"
strcat(buf, "eee"); // пробегает "aaabbbcccddd", пишет "eee"
strcat(buf, "fff"); // пробегает "aaabbbcccdddeee", пишет "fff"
strcat(buf, "ggg"); // пробегает "aaabbbcccdddeeefff", пишет "ggg"
...


ИзопропилSiemarglЭто долго и не всегда нужно.
да и не совсем ясно, из какого пула выделятьЕсли заморачиваться на скорость работы программы, то у каждого thread-а должен быть свой личный heap для временных блоков памяти с коротким временем жизни. Если не заморачиваться, то можно просто использовать heap процесса (malloc/free, глобальные new/delete).
...
Рейтинг: 0 / 0
16.12.2016, 11:36
    #39368434
Siemargl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему крашится при выходе из функции?
Пётр Седов,

Тебе не нравится, что strcat "пробегает" ?

Так а если сравнить с кодом malloc и учесть время на переключение контекста/системный вызов выделения памяти?

Кто не хочет заморачиваться на скорость - пишет на языках с GC.
...
Рейтинг: 0 / 0
16.12.2016, 11:56
    #39368467
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему крашится при выходе из функции?
Пётр СедовMasterZivкто знает что куда портируют?Я знаю, что серьёзные программы повсеместно используют динамическое распределение памяти, поэтому портировать их на embedded платформы без heap-а никто не будет.


Очень странное определение "серьёзные программы".
Давай вкратце: ты неправ.
...
Рейтинг: 0 / 0
16.12.2016, 17:11
    #39368862
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему крашится при выходе из функции?
Да спор ни о чем. Сравнение крокодилов и остановок.
Функции с размером буфера предназначены для защиты готовых программ от кулхацкеров.
А функции которые сами выделяют нужный буфер - для облегчения работы программиста.
Это два совершенно ортогональных направления и совсем не взаимоисключающих.
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / Почему крашится при выходе из функции? / 25 сообщений из 30, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]