Fórum Root.cz

Hlavní témata => Vývoj => Téma založeno: DukePukem 01. 08. 2022, 10:29:38

Název: Lifetime static/global/heap-allocated objektu v C++
Přispěvatel: DukePukem 01. 08. 2022, 10:29:38
Ahoj,

resim ted jeden problem. Mame objekt tridy, rekneme Sluzby:

Kód: [Vybrat]
class Sluzby
{
   std::shared_ptr<Http> klient;
   std::shared_ptr<DB> databaze;
};

Tento objekt musi zit po celou dobu behu aplikace a musi byt prave jeden. Pristupuje se k objektu tedy takto:

Kód: [Vybrat]
Sluzby *sluzbyGlobal = new Sluzby;

tj. je to globalni promenna, na kterou se nikdy nevola delete. Tj. umre az na uplnem konci s celou heap.

Ma nejaky smysl, aby objekty uvnitr (Http klient a DB databaze) byly std::shared_ptr a ne proste staticky alokovane membery nebo alespon std::unique_ptr?

Chce se po mne, abych predaval vsechny reference na Http a DB pomoci kopirovani shared pointeru kvuli tomu, aby "nahodou" napr Http nebyl automaticky dealokovan drive nez ho neco pouzije.

Ja argumentuju tim, ze neexistuje situace, kdy by takto alokovany objekt mohl byt dealokovan drive nez skonci jakekoliv vlakno v cele aplikaci (i detached). Tudiz, prijde mi efektivnejsi predavat vsude proste Http& klient namisto pomalejsiho std::shared_ptr<Http>.

Pokud vim, kdyz se vyskytne neopravitelna chyba (vyjimka pri zpracovani vyjimky, SIGABRT), program okamzite skonci a neceka se na nejake uvolnovani pameti nebo kdesi cosi.

Dale, nemyslim si, ze by se vlakno mohlo nejakou vzacnou chybou stat detached. Pokud jsou vsechny vlakna non-detached, s koncem programu se nasilne takova vlakna ukonci, ze? Tj. drive pred uvolnenim heap/static objektu.

Tj. proc proste nemit tohle:

Kód: [Vybrat]
class Sluzby
{
   Http klient;
   DB databaze;
   static Sluzby& Get()
   {
      static Sluzby instance;
      return instance;
   }
};

?
Název: Re:Lifetime static/global/heap-allocated objektu v C++
Přispěvatel: linuxak 01. 08. 2022, 10:55:58
Nechci se vyjadřovat k celkovému desingu (myslím si o tom svoje), ale není mi jasné, proč chceš předělávat shared_ptr na unique_ptr nebo statickou instanci a tím změnit celý interface? Je kopírování shared_ptr reálný problém, profiloval jsi aplikaci a má smysl to předělat kvůli výkonu? Pokud ne, je to předčasná optimalizace a tím i zbytečná práce.
Název: Re:Lifetime static/global/heap-allocated objektu v C++
Přispěvatel: DukePukem 01. 08. 2022, 11:33:39
Ano, o designu si taky myslim svoje, chci ho zmenit zpusobem jaky navrhuji. Nejde o performance, ale o korektnost a jednoduchost.

Pokud muze byt

Kód: [Vybrat]
Sluzby *sluzbyGlobal = new Sluzby;

dealokovano drive nez skonci kterekoliv vlakno a ja mam napriklad tridu, ktera drzi pointer/referenci na Sluzby:

Kód: [Vybrat]
class MujObjekt
{
   Sluzby& sluzby;

   void foo() { sluzby.klient->post(); }
};

(ano, bohuzel, takhle to v nasi code base je).

tak me std::shared_ptr<Http> nezachrani, protoze uz byl davno dealokovan s celou tridou Sluzby.

Proto se ptam znovu, muze byt globalni/staticka promenna nebo pamet na heap dealokovana drive nez skonci (i detached) vlakna?

Pokud ano, std::shared_ptr<Http> nas nezachrani, pokud ne, nema std::shared_ptr<Http> v tomhle pripade cenu.
Název: Re:Lifetime static/global/heap-allocated objektu v C++
Přispěvatel: linuxak 01. 08. 2022, 13:27:05
Tohle řešení:
Kód: [Vybrat]
class Sluzby
{
   Http klient;
   DB databaze;
   static Sluzby& Get()
   {
      static Sluzby instance;
      return instance;
   }
};
není ekvivalentní vytvoření instance Sluzby na heapu, protože C++ nedefinuje pořadí inicializace statických proměnných v různých kompilačních jednotkách. Pokud něco z instance Sluzby bude používat (konstantní) statickou proměnnou z jiné kompilační jednotky, je to undefined behavior. Ono to tam nemusí být teď, ale možná to tam někdo přidá v budoucnu... Osobně nejsem přiznivcem takového řešení, vytvoření instance Sluzby na heapu tímto problémem netrpí.
Název: Re:Lifetime static/global/heap-allocated objektu v C++
Přispěvatel: alex6bbc 01. 08. 2022, 13:55:33
1) jestlize objekt zije celou dobu, klidne muze byt na stacku a muzes predavat jen jeho referenci.
2) proc ten objekt neudelas jako singleton, tovarni metodu co jej jednou vytvori a nazdar.
3) v modernim c++ uz new a delete nepouzivej, pouzij unique_ptr a pokud nechces v objektu nic menit
tak jen predavej do parametru jeho const raw pointer.
4) pokud chce predavat vlastnictvi unique_ptr tak jako parametr hodnotou a vzdy s move
Název: Re:Lifetime static/global/heap-allocated objektu v C++
Přispěvatel: alex6bbc 01. 08. 2022, 14:17:30
jednoduchy priklad, ze i objekt na stacku muze byt "singleton".
sice jde vytvorit mnoho techto objektu, ale funkcni je jen ten prvni vytvoreny pomoci sid=0.
metody jsou ohnute, ze neco delaji jen kdyz je my_id objektu 0, takze jen prvni instance
funguje spravne.


---------------------------------------------------------------------------
// Singleton je na stacku

#include <iostream>

class Singleton
{
public:
    Singleton(int v) : value(v) { Singleton::sid++; my_id = Singleton::sid; }

    void setValue(int v) { if (my_id == 0) value=v; }
    int getValue() { if (my_id > 0) return 0; return value; }
    void print() { if (my_id > 0) { std::cout << "singleton is bad!" << std::endl; return; } std::cout << "singleton my_id=" << my_id << " value=" << value << std::endl; }

    static int sid;
private:
   
    int my_id;
    int value;
};

int Singleton::sid = -1;



int main()
{
    Singleton dobry(1);
    dobry.setValue(7);
    dobry.print();

    Singleton spatny1(1);
    spatny1.setValue(7);
    spatny1.print();

    Singleton spatny2(2);
    spatny2.setValue(77);
    spatny2.print();

    dobry.setValue(17);
    dobry.print();

    spatny2.setValue(66);
    spatny2.print();

    return 0;
}

Název: Re:Lifetime static/global/heap-allocated objektu v C++
Přispěvatel: Jiří Havel 01. 08. 2022, 14:23:09
Tohle řešení:
Kód: [Vybrat]
class Sluzby
{
   Http klient;
   DB databaze;
   static Sluzby& Get()
   {
      static Sluzby instance;
      return instance;
   }
};
není ekvivalentní vytvoření instance Sluzby na heapu, protože C++ nedefinuje pořadí inicializace statických proměnných v různých kompilačních jednotkách. Pokud něco z instance Sluzby bude používat (konstantní) statickou proměnnou z jiné kompilační jednotky, je to undefined behavior. Ono to tam nemusí být teď, ale možná to tam někdo přidá v budoucnu... Osobně nejsem přiznivcem takového řešení, vytvoření instance Sluzby na heapu tímto problémem netrpí.
Tohle není úplně pravda. U globálních objektů není specifikované pořadí mezi jednotlivými .cpp.
Ale tahle instance se vytvoří při prvním zavolání Get a úklid takových objektů je v opačném pořadí než vznikly.

MujObjekt je asi cajk, protože ta reference se dá nasměrovat na později vzniklý objekt jen divokým prasením. Ale dal bych si bacha na věci, co mají na ty Sluzby ukazatel.

Jinak co se týče vláken, tak c++ vlákna by měla skončit před destrukcí statických a globálních objektů. Ale pokud jde o jiné thready, tak bych byl hodně opatrný až paranoidní. Třeba holé winapi s c++ runtime spolupracuje špatně.
Název: Re:Lifetime static/global/heap-allocated objektu v C++
Přispěvatel: Jiří Havel 01. 08. 2022, 14:44:57
jednoduchy priklad, ze i objekt na stacku muze byt "singleton".
sice jde vytvorit mnoho techto objektu, ale funkcni je jen ten prvni vytvoreny pomoci sid=0.
metody jsou ohnute, ze neco delaji jen kdyz je my_id objektu 0, takze jen prvni instance
funguje spravne.
Bacha, singleton pattern má i další věci. Třeba že existuje nějaký globální přístupový bod k tomu jedinečnému objektu. A to ten váš příklad nesplňuje.

Tomu, že si nějaký jeden objekt vytvořím ručně a rozstrkám ho dál třeba přes dependency injection, se obvykle Singleton neříká. A stejně tak bych od něčeho nazvaného singleton nečekal, že půjde jednoduše vytvořit víc instancí, které se akorát budou jinak chovat.
Název: Re:Lifetime static/global/heap-allocated objektu v C++
Přispěvatel: anonacct 01. 08. 2022, 14:45:57
Vyhoď ten global a pak se teprve můžeš bavit o čistotě nějakého návrhu.
Název: Re:Lifetime static/global/heap-allocated objektu v C++
Přispěvatel: rrrado1 01. 08. 2022, 22:14:18
Mne sa návrh v otázke zdá byť ok. Čo sa týka predávania DB a http cez shared pointer, zdá sa mi to zbytočné, keďže volaná funkcia nepotrebuje ďalej zdieľať vlastníctvo DB. Prvá odpoveď v tomto threade o tom hovorí: https://stackoverflow.com/questions/10826541/passing-shared-pointers-as-arguments.
Název: Re:Lifetime static/global/heap-allocated objektu v C++
Přispěvatel: RDa 01. 08. 2022, 23:55:04
Ja vedel ze C++ je slepa cesta :) jen si hezky onanujte, vy uber-programatori.

Na vse ostatni staci takovy jednodychy on-demand generator:

Citace
typ *single() {
  static typ *instance;
  if (!instance) instance = &new typ();
  return instance;
}
Název: Re:Lifetime static/global/heap-allocated objektu v C++
Přispěvatel: APhacker_mob 02. 08. 2022, 07:10:12
jednoduchy priklad, ze i objekt na stacku muze byt "singleton".
sice jde vytvorit mnoho techto objektu, ale funkcni je jen ten prvni vytvoreny pomoci sid=0.
metody jsou ohnute, ze neco delaji jen kdyz je my_id objektu 0, takze jen prvni instance
funguje spravne.
Bacha, singleton pattern má i další věci. Třeba že existuje nějaký globální přístupový bod k tomu jedinečnému objektu. A to ten váš příklad nesplňuje.

Tomu, že si nějaký jeden objekt vytvořím ručně a rozstrkám ho dál třeba přes dependency injection, se obvykle Singleton neříká. A stejně tak bych od něčeho nazvaného singleton nečekal, že půjde jednoduše vytvořit víc instancí, které se akorát budou jinak chovat.

Neni pristupovy bod ta globalni instance? Pokud nepotrebuje lazy inicializaci, nevidim problem.
Název: Re:Lifetime static/global/heap-allocated objektu v C++
Přispěvatel: Jiří Havel 02. 08. 2022, 09:24:37
jednoduchy priklad, ze i objekt na stacku muze byt "singleton".
sice jde vytvorit mnoho techto objektu, ale funkcni je jen ten prvni vytvoreny pomoci sid=0.
metody jsou ohnute, ze neco delaji jen kdyz je my_id objektu 0, takze jen prvni instance
funguje spravne.
Bacha, singleton pattern má i další věci. Třeba že existuje nějaký globální přístupový bod k tomu jedinečnému objektu. A to ten váš příklad nesplňuje.

Tomu, že si nějaký jeden objekt vytvořím ručně a rozstrkám ho dál třeba přes dependency injection, se obvykle Singleton neříká. A stejně tak bych od něčeho nazvaného singleton nečekal, že půjde jednoduše vytvořit víc instancí, které se akorát budou jinak chovat.

Neni pristupovy bod ta globalni instance? Pokud nepotrebuje lazy inicializaci, nevidim problem.
Ale alex nepsal o žádné globální instanci. V tom jeho příkladu byl "globální" akorát couter na základě kterého mohl ten nesingleton poznat, že je první. K těm samotným objektům na stacku žádný globální přístup nebyl.
Název: Re:Lifetime static/global/heap-allocated objektu v C++
Přispěvatel: Jiří Havel 02. 08. 2022, 09:58:56
Ja vedel ze C++ je slepa cesta :) jen si hezky onanujte, vy uber-programatori.

Na vse ostatni staci takovy jednodychy on-demand generator:

Citace
typ *single() {
  static typ *instance;
  if (!instance) instance = &new typ();
  return instance;
}
Supr, tak sis kopl a navíc taky neodpověděl na to, na co se tazatel ptal.

Mimochodem, ten jednoduchý on demand generátor na všechno rozhodně nestačí. Minimálně proto, že není thread-safe. A tazatel se ptal na thready, takže mu to nejspíš vadit bude.
Název: Re:Lifetime static/global/heap-allocated objektu v C++
Přispěvatel: echo_zulu 02. 08. 2022, 11:55:28
Ja vedel ze C++ je slepa cesta :) jen si hezky onanujte, vy uber-programatori.

Na vse ostatni staci takovy jednodychy on-demand generator:

Citace
typ *single() {
  static typ *instance;
  if (!instance) instance = &new typ();
  return instance;
}

To céčku je naozaj nutné kontrolovať, či statická premenná vo funkcii bola inicializovaná?

V C++ nie je, jednoducho to prebehne iba pri prvom volaní a platí to aj pre tú alokáciu pamäte.

A od C+11 je to aj thread-safe...
Název: Re:Lifetime static/global/heap-allocated objektu v C++
Přispěvatel: anonacct 02. 08. 2022, 12:19:08
Spíš jde o to tu proměnnou "lazy" zinicializovat až když je opravdu potřeba, statická inicializace v C++ je tak trochu nepředvídatelná a spoláhat se na ni je cesta do pekel - proto bych vyhodil všechny globals a měl jen jeden - nějaký DI context nebo aplikační kontext, atd... popřípadě nemít ani ten a předávat ten kontext. Asi záleží na tom jak je kód na kterém tazatel děla starý - obvykle starší code-base má hodně globálních proměnných a něco s tím udělat by bylo na roky práce...
Název: Re:Lifetime static/global/heap-allocated objektu v C++
Přispěvatel: Jiří Havel 02. 08. 2022, 13:30:56
Ja vedel ze C++ je slepa cesta :) jen si hezky onanujte, vy uber-programatori.

Na vse ostatni staci takovy jednodychy on-demand generator:

Citace
typ *single() {
  static typ *instance;
  if (!instance) instance = &new typ();
  return instance;
}

To céčku je naozaj nutné kontrolovať, či statická premenná vo funkcii bola inicializovaná?

V C++ nie je, jednoducho to prebehne iba pri prvom volaní a platí to aj pre tú alokáciu pamäte.

A od C+11 je to aj thread-safe...
Pokud je ta statická proměnná ukazatel na dynamicky alokovaný objekt, tak je to nutné kontrolovat. V C++11 je thread safe tahle verze :
Citace
typ *single() {
  static typ instance;
  return &instance;
}
Protože thread safe je jen ta samotná inicializace statické proměnné.

Spíš jde o to tu proměnnou "lazy" zinicializovat až když je opravdu potřeba, statická inicializace v C++ je tak trochu nepředvídatelná a spoláhat se na ni je cesta do pekel - proto bych vyhodil všechny globals a měl jen jeden - nějaký DI context nebo aplikační kontext, atd... popřípadě nemít ani ten a předávat ten kontext. Asi záleží na tom jak je kód na kterém tazatel děla starý - obvykle starší code-base má hodně globálních proměnných a něco s tím udělat by bylo na roky práce...
Globální proměnné jsou problematické, ale statická proměnná uvnitř funkce je v pohodě. Ta se zinicializuje ve chvíli, kdy se ta funkce poprvé zavolá.
Název: Re:Lifetime static/global/heap-allocated objektu v C++
Přispěvatel: RDa 02. 08. 2022, 13:34:54
Mimochodem, ten jednoduchý on demand generátor na všechno rozhodně nestačí. Minimálně proto, že není thread-safe. A tazatel se ptal na thready, takže mu to nejspíš vadit bude.

Jiste ze to neni thread safe, protoze prirazeni ani { } si takovou extra namahu nedava.

To céčku je naozaj nutné kontrolovať, či statická premenná vo funkcii bola inicializovaná?
V C++ nie je, jednoducho to prebehne iba pri prvom volaní a platí to aj pre tú alokáciu pamäte.
A od C+11 je to aj thread-safe...

Pokud pisu zdrojak, pisu ho tak, abych nemusel poskytovat out-of-band informaci, jakou verzi standardu se na to ma prekladac divat.

U C++11 musite ale pouzit safe:: nebo tam plati nejake magicke pravidlo / vyjimka na kod podobny memu?

Nez jsem dopsal prispevek, tak se to zodpovedelo..

Pokud je ta statická proměnná ukazatel na dynamicky alokovaný objekt, tak je to nutné kontrolovat. V C++11 je thread safe tahle verze :
Citace
typ *single() {
  static typ instance;
  return &instance;
}
Protože thread safe je jen ta samotná inicializace statické proměnné.

Název: Re:Lifetime static/global/heap-allocated objektu v C++
Přispěvatel: anonacct 02. 08. 2022, 15:07:59
Citace
Globální proměnné jsou problematické, ale statická proměnná uvnitř funkce je v pohodě. Ta se zinicializuje ve chvíli, kdy se ta funkce poprvé zavolá.

Jo, a kdy se zničí ta statická proměnná? Jediná možnost v tomto případě je udělat leak a alokovat ji na heapu a nikdy ji nezničit (takže mít static pointer).

Jinak thread safe inicialization má compile flag - pokud někdo kompiluje bez tak tyto hrátky se statickýma proměnnýma nejsou ani thread safe.
Název: Re:Lifetime static/global/heap-allocated objektu v C++
Přispěvatel: Jiří Havel 02. 08. 2022, 15:09:41
Pokud pisu zdrojak, pisu ho tak, abych nemusel poskytovat out-of-band informaci, jakou verzi standardu se na to ma prekladac divat.
Mám to chápat tak, že píšete v c++98 abyste ke všem těm out-of-band informacím jako jsou cesty ke knihovnám, úrovně optimalizací a další nastavení prostředí nemusel přidat jeden další parametr?

Všiml jste si, že všechny běžně používané jazyky přicházejí s novýma verzema, kde se (obvykle úspěšně) snaží programátorům ulehčit práci? A každý příčetný programátor tu out-of-band informaci rád poskytne aby nemusel používat prehistorickou verzi 0.666 z hlubin pekelných, pokud to není nezbytně nutné. :D
Název: Re:Lifetime static/global/heap-allocated objektu v C++
Přispěvatel: RDa 02. 08. 2022, 15:19:21
Všiml jste si, že všechny běžně používané jazyky přicházejí s novýma verzema, kde se (obvykle úspěšně) snaží programátorům ulehčit práci? A každý příčetný programátor tu out-of-band informaci rád poskytne aby nemusel používat prehistorickou verzi 0.666 z hlubin pekelných, pokud to není nezbytně nutné. :D

To mate jako se zavorkama a prioritama operatoru.. pridavam je i na mista kam bych nemusel, jen abych nemrhal mozkovymi cykly nad premyslenim co se provede driv. Asi mam v oblibe primitivni jistoty?

A v mem kodu taky najdete samostatne stojici bloky mezi { }, aniz by pred tim byla podminka - a kdyz uz je, je to vetsinou neco jako if (1), casteji tam ale byva comment pro celou grupu. Pro stroj je to zbytecny.. ale pro nas je tato moznost darem. Ne vzdy je nejkompaktnejsi zdrojak ten nejlepsi - hranici optimalna ale muzeme mit samozrejme jinde.
Název: Re:Lifetime static/global/heap-allocated objektu v C++
Přispěvatel: Jiří Havel 02. 08. 2022, 15:23:59
Citace
Globální proměnné jsou problematické, ale statická proměnná uvnitř funkce je v pohodě. Ta se zinicializuje ve chvíli, kdy se ta funkce poprvé zavolá.

Jo, a kdy se zničí ta statická proměnná? Jediná možnost v tomto případě je udělat leak a alokovat ji na heapu a nikdy ji nezničit (takže mít static pointer).
Statické proměnné se ničí při ukončování programu a to v opačném pořadí než vznikly. Trochu jako by se hned po tom vytvoření zavolal atexit.
Takže abyste se na tu proměnnou dostal po jejím zničení, musel byste na ni lézt z nějakého objektu, který existoval už předtím. To je poměrně obskurní použití, takže to moc nehrozí. Pokud nějaký sigleton potřebuje jiné singletony, pak stačí aby si o ně řekl už v konstruktoru a je za vodou.
Všechny implementace singletonů mají své pasti a tahle je na tom ještě docela v pohodě.
Citace
Jinak thread safe inicialization má compile flag - pokud někdo kompiluje bez tak tyto hrátky se statickýma proměnnýma nejsou ani thread safe.
Přes compile flagy se dá nastavit spousta dalších věcí - výjimky, RTTI, přesnost floatů, ... Pokud někdo vrtá do tohohle, tak holt musí vědět moc dobře, co dělá.
Název: Re:Lifetime static/global/heap-allocated objektu v C++
Přispěvatel: Jiří Havel 02. 08. 2022, 15:44:48
Všiml jste si, že všechny běžně používané jazyky přicházejí s novýma verzema, kde se (obvykle úspěšně) snaží programátorům ulehčit práci? A každý příčetný programátor tu out-of-band informaci rád poskytne aby nemusel používat prehistorickou verzi 0.666 z hlubin pekelných, pokud to není nezbytně nutné. :D

To mate jako se zavorkama a prioritama operatoru.. pridavam je i na mista kam bych nemusel, jen abych nemrhal mozkovymi cykly nad premyslenim co se provede driv. Asi mam v oblibe primitivni jistoty?

A v mem kodu taky najdete samostatne stojici bloky mezi { }, aniz by pred tim byla podminka - a kdyz uz je, je to vetsinou neco jako if (1), casteji tam ale byva comment pro celou grupu. Pro stroj je to zbytecny.. ale pro nas je tato moznost darem. Ne vzdy je nejkompaktnejsi zdrojak ten nejlepsi - hranici optimalna ale muzeme mit samozrejme jinde.
Tohle ale můžete dělat i v těch nových verzích. Ulehčením práce jsem opravdu nemyslel co nejkratší kód, ale právě kód kde se můžu soustředit na to důležité. A nové verze c++ imo přinesly pěkných pár věcí, co se chovají daleko příčetněji než starý binec.
Název: Re:Lifetime static/global/heap-allocated objektu v C++
Přispěvatel: DukePukem 02. 08. 2022, 17:36:55
Dekuji vsem za odpovedi.

Par poznamek:

1) Kdyby bylo po mem, staticky (tj. na stacku) bych naalokoval vse v mainu, predaval referenci v konstruktoru (umoznuje dependency injection) a zajistil graceful shutdown. Po mem ale bohuzel neni, ponevadz manazer lpi na globalni promenne (kvuli egu a protoze C++ nerozumi). Ja bych delal spoustu veci jinak.

2) Inicializace statickych, block-scoped promennych je skutecne thread-safe. Vygooglete si nasledujici vetu v C++ standardu:
Kód: [Vybrat]
If control enters the declaration concurrently while the variable is being initialized, the concurrent execution shall wait for completion of the initializationTenhle singleton taktez nese jmeno Scotta Meyerse: https://laristra.github.io/flecsi/src/developer-guide/patterns/meyers_singleton.html (https://laristra.github.io/flecsi/src/developer-guide/patterns/meyers_singleton.html). Soudim tedy, ze je to safe.

3) Rozumim-li spravne postu o kompilacnim flagu, pak je to nejspis toto:
Kód: [Vybrat]
-fno-threadsafe-statics
Do not emit the extra code to use the routines specified in the C++ ABI for thread-safe initialization of local statics. You can use this option to reduce code size slightly in code that doesn’t need to be thread-safe.
Z toho mi plyne, ze tento flag vypina thread-safety, tudiz defaultne je to safe.

Ale abych se vratil k otazce.

Trochu to prezenu, abych zduraznil absurditu :) Je mozne pristoupit k objektu na heap po korektnim zniceni cele heap v bezicim procesu? Tj. dobehnou vlakna, znici se heap a TED je ten okamzik :) Muze v tomto bode jeste napriklad bezet detached vlakno?

Lze to same udelat s korektne - na konci programu - dealokovanou statickou promennou?

Pokud nikoliv, vubec neni potreba tridu Sluzby dynamicky alokovat a uz vubec managovat ji nebo jeji membery pomoci std::shared_ptr.

A sem se snazim celou dobu dostat. Respektive, chci vedet, jestli neco neopomijim.
Název: Re:Lifetime static/global/heap-allocated objektu v C++
Přispěvatel: tecka 03. 08. 2022, 07:53:09
Ale alex nepsal o žádné globální instanci. V tom jeho příkladu byl "globální" akorát couter na základě kterého mohl ten nesingleton poznat, že je první. K těm samotným objektům na stacku žádný globální přístup nebyl.
Singletony se dělají tak, že vytvářím jen jednu instanci a ne, že namatlám třídu, která nedovolí víc než jednu instanci. Nebo si je dokonce počítá a u jiných než první se rozhodne nefungovat.

Jestli v jednom člověku píšete a testujete helloworldy, tak si klidně hrajte s nesmysly, co jste se minulý týden naučili ve škole, ale nechoďte s tím mezi lidi.
Název: Re:Lifetime static/global/heap-allocated objektu v C++
Přispěvatel: tecka 03. 08. 2022, 07:54:17
Ma nejaky smysl, aby objekty uvnitr (Http klient a DB databaze) byly std::shared_ptr a ne proste staticky alokovane membery nebo alespon std::unique_ptr?

Chce se po mne, abych predaval vsechny reference na Http a DB pomoci kopirovani shared pointeru kvuli tomu, aby "nahodou" napr Http nebyl automaticky dealokovan drive nez ho neco pouzije.
Má to přesně ten smysl uvedený v dalším odstavci. Zadavatel/nadřízený si nejspíš uvědomuje, že kód má tendeci se vyvíjet a měnit, ten pointer nemusí být navždy unikátní a raw-pointer dříve nebo později někdo dokope. Nezáleží na tom, že zrovna teď zrovna v tomhle případě není nutný. Ničemu nevadí a předchází problému. Když se to po tobě takhle chce, tak to takhle udělej.
Název: Re:Lifetime static/global/heap-allocated objektu v C++
Přispěvatel: Jiří Havel 03. 08. 2022, 08:51:09
Ale abych se vratil k otazce.

Trochu to prezenu, abych zduraznil absurditu :) Je mozne pristoupit k objektu na heap po korektnim zniceni cele heap v bezicim procesu? Tj. dobehnou vlakna, znici se heap a TED je ten okamzik :) Muze v tomto bode jeste napriklad bezet detached vlakno?
Jo, zničit heap v běžícím procesu samozřejmě jde. Ale já teda nepotkal platformu, kde by se při ukončování likvidoval normální heap. Vždycky to zůstalo viset a tu paměť pak poklidil OS. Spousta programů nechává viset objekty, které nepotřebujou volat destruktory. Takže příčetné runtimy se úklidem heapu na konci neobtěžují. Akorát Valgrind a spol. v takovém případě kvičí.
Citace
Pokud nikoliv, vubec neni potreba tridu Sluzby dynamicky alokovat a uz vubec managovat ji nebo jeji membery pomoci std::shared_ptr.
Jedna motivace může být i variace na PIMPL. Pokud uživatelé té Sluzby nepotřebují vždycky všechno, tak nemusí includovat potenciálně dost veliké headery s hromadou symbolů ale pro nepoužité věci jim stačí forward deklarace. U velikého projektu to může být zajímavá úspora nejen času kompilace ale i místa na disku pro objektové soubory.
Název: Re:Lifetime static/global/heap-allocated objektu v C++
Přispěvatel: DukePukem 03. 08. 2022, 13:09:32
Ma nejaky smysl, aby objekty uvnitr (Http klient a DB databaze) byly std::shared_ptr a ne proste staticky alokovane membery nebo alespon std::unique_ptr?

Chce se po mne, abych predaval vsechny reference na Http a DB pomoci kopirovani shared pointeru kvuli tomu, aby "nahodou" napr Http nebyl automaticky dealokovan drive nez ho neco pouzije.
Má to přesně ten smysl uvedený v dalším odstavci. Zadavatel/nadřízený si nejspíš uvědomuje, že kód má tendeci se vyvíjet a měnit, ten pointer nemusí být navždy unikátní a raw-pointer dříve nebo později někdo dokope. Nezáleží na tom, že zrovna teď zrovna v tomhle případě není nutný. Ničemu nevadí a předchází problému. Když se to po tobě takhle chce, tak to takhle udělej.

Slysel jste nekdy o YAGNI? A kdybych mel vzdycky delat jen to, co se po mne chce, asi bych byl porad jeste junior... :)

Ale abych se vratil k otazce.

Trochu to prezenu, abych zduraznil absurditu :) Je mozne pristoupit k objektu na heap po korektnim zniceni cele heap v bezicim procesu? Tj. dobehnou vlakna, znici se heap a TED je ten okamzik :) Muze v tomto bode jeste napriklad bezet detached vlakno?
Jo, zničit heap v běžícím procesu samozřejmě jde. Ale já teda nepotkal platformu, kde by se při ukončování likvidoval normální heap. Vždycky to zůstalo viset a tu paměť pak poklidil OS. Spousta programů nechává viset objekty, které nepotřebujou volat destruktory. Takže příčetné runtimy se úklidem heapu na konci neobtěžují. Akorát Valgrind a spol. v takovém případě kvičí.

Moment moment, jde tohle udelat pomoci standardniho C++ runtimu? (tj. NE volanim noveho processu z C kodu). Predpokladam, ze to bude nejaky unixovy system call, ne?
Název: Re:Lifetime static/global/heap-allocated objektu v C++
Přispěvatel: Jiří Havel 03. 08. 2022, 14:48:34
Ale abych se vratil k otazce.

Trochu to prezenu, abych zduraznil absurditu :) Je mozne pristoupit k objektu na heap po korektnim zniceni cele heap v bezicim procesu? Tj. dobehnou vlakna, znici se heap a TED je ten okamzik :) Muze v tomto bode jeste napriklad bezet detached vlakno?
Jo, zničit heap v běžícím procesu samozřejmě jde. Ale já teda nepotkal platformu, kde by se při ukončování likvidoval normální heap. Vždycky to zůstalo viset a tu paměť pak poklidil OS. Spousta programů nechává viset objekty, které nepotřebujou volat destruktory. Takže příčetné runtimy se úklidem heapu na konci neobtěžují. Akorát Valgrind a spol. v takovém případě kvičí.

Moment moment, jde tohle udelat pomoci standardniho C++ runtimu? (tj. NE volanim noveho processu z C kodu). Predpokladam, ze to bude nejaky unixovy system call, ne?
Můžete mít několik heapů tak, že použijete víc alokátorů. Nebo ve winapi máte třeba CreateHeap, takže si můžete vytvořit další heapy.

V c++ standardní knihovně nemáte možnost si nějaké další heapy přímo vytvořit, ale jinak je to na víc heapů připravené. Přece jenom, alokátor v kontejnerech není nic jiného než handle k nějakému heapu.
Název: Re:Lifetime static/global/heap-allocated objektu v C++
Přispěvatel: Wavelet 03. 08. 2022, 17:00:36
"Slysel jste nekdy o YAGNI? A kdybych mel vzdycky delat jen to, co se po mne chce, asi bych byl porad jeste junior... :)"
No nevím, pocit že jsi chytřejší než ostatní je často dosti příznačné pro ... doplň si sám. Jak se říká: "Never trust a programmer who says he knows C++"  ;)
Název: Re:Lifetime static/global/heap-allocated objektu v C++
Přispěvatel: DukePukem 04. 08. 2022, 07:02:44
"Slysel jste nekdy o YAGNI? A kdybych mel vzdycky delat jen to, co se po mne chce, asi bych byl porad jeste junior... :)"
No nevím, pocit že jsi chytřejší než ostatní je často dosti příznačné pro ... doplň si sám. Jak se říká: "Never trust a programmer who says he knows C++"  ;)

Omg, ja se na to, na co odpovidal vubec neptal. Jestli neznate C++ nebo se bojite, ze vam nekdo dokope pointery a vy si to neumite pohlidat, pak bezte programovat v Jave a neplette se do diskuzi o C++.
Název: Re:Lifetime static/global/heap-allocated objektu v C++
Přispěvatel: Wavelet 04. 08. 2022, 17:12:20
"Slysel jste nekdy o YAGNI? A kdybych mel vzdycky delat jen to, co se po mne chce, asi bych byl porad jeste junior... :)"
No nevím, pocit že jsi chytřejší než ostatní je často dosti příznačné pro ... doplň si sám. Jak se říká: "Never trust a programmer who says he knows C++"  ;)

Omg, ja se na to, na co odpovidal vubec neptal. Jestli neznate C++ nebo se bojite, ze vam nekdo dokope pointery a vy si to neumite pohlidat, pak bezte programovat v Jave a neplette se do diskuzi o C++.

Jasně, takže junior  8)
Název: Re:Lifetime static/global/heap-allocated objektu v C++
Přispěvatel: DukePukem 04. 08. 2022, 18:18:21
"Slysel jste nekdy o YAGNI? A kdybych mel vzdycky delat jen to, co se po mne chce, asi bych byl porad jeste junior... :)"
No nevím, pocit že jsi chytřejší než ostatní je často dosti příznačné pro ... doplň si sám. Jak se říká: "Never trust a programmer who says he knows C++"  ;)

Omg, ja se na to, na co odpovidal vubec neptal. Jestli neznate C++ nebo se bojite, ze vam nekdo dokope pointery a vy si to neumite pohlidat, pak bezte programovat v Jave a neplette se do diskuzi o C++.

Jasně, takže junior  8)

Jestli pak konecne opustite tuhle diskuzi, pak ano, klidne si to myslete...