- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
#include <iostream>
#include <string>
#include <string_view>
int main() {
std::string s = "Hellooooooooooooooo ";
std::string_view sv = s + "World\n";
std::cout << sv;
}
Нашли или выдавили из себя код, который нельзя назвать нормальным, на который без улыбки не взглянешь? Не торопитесь его удалять или рефакторить, — запостите его на говнокод.ру, посмеёмся вместе!
+4
#include <iostream>
#include <string>
#include <string_view>
int main() {
std::string s = "Hellooooooooooooooo ";
std::string_view sv = s + "World\n";
std::cout << sv;
}
https://alexgaynor.net/2019/apr/21/modern-c++-wont-save-us/
What's happening here is that s + "World\n" allocates a new std::string, and then is converted to a std::string_view. At this point the temporary std::string is freed, but sv still points at the memory that used to be owned by it. Any future use of sv is a use-after-free vulnerability. Oops! C++ lacks the facilities for the compiler to be aware that sv captures a reference to something where the reference lives longer than the referent. The same issue impacts std::span, also an extremely modern C++ type.
guest8 24.04.2019 03:09 # −999
guest8 24.04.2019 03:20 # −999
someone 24.04.2019 11:14 # +3
Steve_Brown 25.04.2019 11:01 # 0
guest8 25.04.2019 21:07 # −999
Steve_Brown 26.04.2019 12:24 # 0
guest8 26.04.2019 13:39 # −999
guest8 25.04.2019 21:05 # −999
bormand 24.04.2019 07:36 # 0
bormand 24.04.2019 08:01 # +1
Странно было бы, если бы string_view, который создан как быстрая обёртка над куском существующей строки, работал иначе.
j123123 24.04.2019 08:35 # +2
Вот именно поэтому я за Си. Там ничего просто так не дохнет.
bormand 24.04.2019 08:40 # +1
PACTPOBblu_nemyx 24.04.2019 12:17 # 0
guest8 24.04.2019 12:41 # −999
bormand 24.04.2019 15:41 # +1
У каждой функции как правило внятный контракт. Иногда даже на уровне одной либы они совпадают. Но в целом, когда у тебя в проге юзается несколько либ - это лютый треш, о котором постоянно надо думать.
Или я просто отупел после крестов, где я по каждой внешней функции читаю доку ровно один раз - чтобы сделать над ней RAII обёртку?
guest8 24.04.2019 16:02 # −999
bormand 24.04.2019 17:27 # +4
В крестах его держать под контролем ничуть не сложнее, имхо.
> пример треша
Да банально - в одной либе тебе возвращают хуйню, на которой ты должен LocalFree, во второй - просто free, в третьей - HuiPizdaFree. Где-то надо самому буфер подготовить (и позвать перед этим с нулём для оценки размера). Где-то тебе вернут указатель на кишки структуры который вообще удалять нельзя. Каждая либа вроде и консистентна, но в целом по проекту выходит каша.
Вот в том же openssl даже в пределах одной либы не всегда понятно надо ли освобождать поинтер. Благо в последних версиях они эту инфу в сигнатуру функций стали включать...
Вот здесь и спасают крестообёртки и крестосмартпоинтеры.
j123123 24.04.2019 19:52 # 0
Так и запишем - C++ это язык для подкостыливания сишечки.
bormand 24.04.2019 19:55 # 0
j123123 24.04.2019 20:19 # 0
j123123 24.04.2019 20:24 # 0
PACTPOBblu_nemyx 24.04.2019 20:53 # 0
j123123 24.04.2019 21:02 # 0
PACTPOBblu_nemyx 24.04.2019 22:31 # 0
https://github.com/bormand/pp_aes
guest8 24.04.2019 22:46 # −999
OCETuHCKuu_nemyx 24.04.2019 22:51 # 0
> Превращает govnokod.ru в анонимную борду
Можно говносток и хуз сделать анонимными.
guest8 24.04.2019 23:02 # −999
gost 24.04.2019 23:08 # 0
j123123 29.12.2019 04:16 # 0
guest8 29.12.2019 04:21 # −999
cmepmop 24.04.2019 20:21 # +3
Только аппарат Илизарова он не снимает уже очень долго, всё подкручивает к нему шурушки.
AHCKujlbHblu_netyx 24.04.2019 23:14 # +3
PACTPOBblu_nemyx 26.04.2019 13:59 # −1
guest8 24.04.2019 23:12 # −999
guest8 24.04.2019 23:13 # −999
AHCKujlbHblu_netyx 24.04.2019 23:18 # 0
guest8 25.04.2019 00:20 # −999
bormand 24.04.2019 17:51 # +1
Блядь, как у вас хватает на это памяти и внимания!? И ещё остаётся на суть задачи...
guest8 24.04.2019 23:14 # −999
j123123 26.04.2019 21:14 # 0
cmepmop 26.04.2019 21:26 # 0
@if(c == NULL) return EXIT_FAILURE;
А разве аллокатор молча не швыряет исключение?
Хм. Погуглил. Инфы по CRT крайне мало, но я полагаю, что это обёртка над VirtualAlloc. Тогда тем более нужен обработчик, швыряющий исключение при неудачном вызове.
gost 26.04.2019 21:29 # 0
«new (std::nothrow)» — не швыряет, возвращает «nullptr».
«malloc»/«calloc» — не швыряют, возвращают «NULL».
Ну и j123123 привёл пример на «C», в нём нет никаких «исключений», и именно поэтому я за.
guest8 26.04.2019 21:31 # −999
cmepmop 26.04.2019 21:36 # 0
procedure malloc(var P:Pointer; Size:DWORD);
begin
P:=Pointer(GlobalAlloc(GPTR, Size));
if P=nil then
raise ENotEnoughMemException.Create('Вы соснули с заглотом');
end;
guest8 26.04.2019 22:01 # −999
cmepmop 26.04.2019 22:06 # 0
Речь вообще-то идёт о try.. catch..throw
guest8 26.04.2019 22:07 # −999
PACTPOBblu_nemyx 26.04.2019 22:11 # 0
guest8 26.04.2019 22:43 # −999
PACTPOBblu_nemyx 27.04.2019 00:09 # 0
cmepmop 27.04.2019 00:39 # 0
cmepmop 27.04.2019 00:40 # 0
cmepmop 27.04.2019 00:40 # 0
cmepmop 27.04.2019 00:41 # 0
guest8 26.04.2019 21:31 # −999
cmepmop 26.04.2019 21:40 # 0
guest8 26.04.2019 22:00 # −999
cmepmop 26.04.2019 22:04 # 0
guest8 26.04.2019 22:06 # −999
cmepmop 26.04.2019 22:10 # 0
https://docs.microsoft.com/en-us/previous-versions/ms810627(v=msdn.10)
When memory is committed, physical pages of memory are allocated and space is reserved in a pagefile.
guest8 26.04.2019 22:20 # −999
PACTPOBblu_nemyx 26.04.2019 22:15 # 0
CRT может при старте вызвать VirtualAlloc (или ещё какой-нибудь ...Alloc) с запасом, а потом вызывать не на каждый malloc, а по необходимости. Внутри куска, выделенного VirtualAlloc, CRT может вводить свою разметку.
PACTPOBblu_nemyx 26.04.2019 22:21 # 0
https://en.wikipedia.org/wiki/C_dynamic_memory_allocation#Implementati ons
Если бы функция malloc была тупой обёрткой, столько реализаций не появилось бы.
guest8 26.04.2019 22:24 # −999
guest8 26.04.2019 22:34 # −999
gost 26.04.2019 23:03 # 0
gost 26.04.2019 23:05 # 0
А «heap_alloc_dbg_internal» оперирует двусвязным списком вот таких штруктур:
guest8 27.04.2019 02:15 # −999
gost 27.04.2019 09:28 # 0
Это такой noexcept в старых крестах.
> Это вообще няшная или кресты?
Кресты. Микрософтный CRT на них написан.
ASD_77 24.04.2019 14:03 # −1
j123123 25.04.2019 10:14 # +3
> Суть проблемы
> В общем, оказывается, что строки содержат ссылки на родительские строки! Что??
> Это вроде бы не сильно на что-то влияет, но только до тех пор, пока вы не захотите из огромной строки вырезать маленький кусочек и оставить себе, а большую строку удалить. Ведь она не удалится. Она останется в памяти, потому что на неё ссылается новая строка, которую вы где-то сохранили, поэтому сборщик мусора не хочет может освободить память.
> Получается такая цепочка указателей:
> какой-то массив или объект -> ваша новая маленькая строка -> старая большая строка
> На самом деле всё ещё сложнее, у строки может быть несколько «родителей», но не будем усугублять.
j123123 25.04.2019 10:16 # +1
PACTPOBblu_nemyx 25.04.2019 10:45 # +2
gost 25.04.2019 10:57 # +1
j123123 24.09.2021 13:19 # 0
3.14159265 25.09.2021 17:31 # 0
> Issue 2869: Substring of huge string retains huge string in memory
> Tue, Sep 3, 2013, 6:47 PM GMT+3
> Status: Assigned (Open)
bormand 25.04.2019 11:01 # +1
PACTPOBblu_nemyx 25.04.2019 11:05 # 0
bormand 25.04.2019 11:12 # +1
j123123 25.04.2019 21:04 # 0
guest8 25.04.2019 21:07 # −999
j123123 25.04.2019 23:45 # +4
CHayT 26.04.2019 12:42 # +2
guest8 26.04.2019 13:38 # −999
CHayT 26.04.2019 14:34 # 0
Ну это более разумный подход, большая арена по сути.
CBuHOKYP 26.09.2021 23:22 # 0
CEHT9I6PbCKuu_nemyx 24.09.2021 13:24 # +2
3.14159265 25.09.2021 17:19 # +1
Какой IntelliJ )))
https://intellij-support.jetbrains.com/hc/en-us/community/posts/206964525-why-does-idea-have-a-run-gc-button-
CBuHOKYP 26.09.2021 23:21 # 0
3.14159265 25.09.2021 17:26 # 0
> А если выжила всего пара мелких фрагментов - можно их скопировать и ёбнуть оригинал.
Я кстати предлагал похожий вореант.
Когда сборщик сталкивается с high memory pressure он должен начинать компактизировать строки, а не вываливаться с OOM.
https://govnokod.ru/27616#comment664929