powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Почему крашится при выходе из функции?
25 сообщений из 30, страница 1 из 2
Почему крашится при выходе из функции?
    #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
Почему крашится при выходе из функции?
    #39365751
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Под конец строки забыл место выделить
Код: plaintext
1.
char *str = malloc(strlen(a) + strlen(b) + 1);
...
Рейтинг: 0 / 0
Почему крашится при выходе из функции?
    #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
Почему крашится при выходе из функции?
    #39365756
Eolt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TПод конец строки забыл место выделить
Код: plaintext
1.
char *str = malloc(strlen(a) + strlen(b) + 1);



Действительно! Теперь работает как надо)
...
Рейтинг: 0 / 0
Почему крашится при выходе из функции?
    #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
Почему крашится при выходе из функции?
    #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
Почему крашится при выходе из функции?
    #39365789
Eolt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZiv,

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

Надо преобразовывать строки в какой-нибудь vector<string> и работать уже с ним?
...
Рейтинг: 0 / 0
Почему крашится при выходе из функции?
    #39365849
egorych
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
EoltКак я понимаю, тип char и функции strcpy и strcat использовать не безопасно?это такой специфик от майкрософта, объявлять стандартные функции из CRTL депрекатед. Нужно для того, чтобы нельзя было написать переносимый код, я так щитаю ))
...
Рейтинг: 0 / 0
Почему крашится при выходе из функции?
    #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
Почему крашится при выходе из функции?
    #39366505
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
EoltMasterZiv,

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

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


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

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

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

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


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

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

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

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

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

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

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

Это ненормальное решение для С, да и вообще, потому что не всегда выделение памяти вообще возможно.
Представь себе архитектуру, где malloc всегда возвращает 0...
...
Рейтинг: 0 / 0
Почему крашится при выходе из функции?
    #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
Почему крашится при выходе из функции?
    #39367470
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пётр Седов,
кто знает что куда портируют?
ты предлагаешь туда еще и CRT всегда портировать?
...
Рейтинг: 0 / 0
Почему крашится при выходе из функции?
    #39367662
Siemargl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пётр СедовMasterZivпроблемы в том, что strcpy и strcat и некоторые другие функции CRTL в принципе не могут контролировать переполнение буфера памяти, куда они пишут - у них нет соответствующего входного параметра, размера буфера.

чтобы преодолеть эти проблемы, в современных версиях CRTL включают новые функции, аналогичные по назначению старым, но с дополнительными параметрами, позволяющими контролировать размер выходного буфера.Создание аналогов старых C-шных функций с дополнительным параметром «длина буфера, в который писать результат» -- это костыльное решение. Нормальное решение -- если функция возвращает строку в качестве результата, то она и выделяет память под строку, а пользователь функции должен эту память освободить.Это долго и не всегда нужно.
...
Рейтинг: 0 / 0
Почему крашится при выходе из функции?
    #39367939
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SiemarglЭто долго и не всегда нужно.
да и не совсем ясно, из какого пула выделять
...
Рейтинг: 0 / 0
Почему крашится при выходе из функции?
    #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
Почему крашится при выходе из функции?
    #39368434
Siemargl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пётр Седов,

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

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

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


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


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