Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > de.comp.lang.iso-c++ > #2100

Re: std::locale steht im Wald

From ram@zedat.fu-berlin.de (Stefan Ram)
Newsgroups de.comp.lang.iso-c++
Subject Re: std::locale steht im Wald
Date 2018-12-15 04:39 +0000
Organization Stefan Ram
Message-ID <facet-20181215053240@ram.dialup.fu-berlin.de> (permalink)
References <pv0pev$n89$1@dont-email.me>

Show all headers | View raw


Udo Steinbach <trashcan@udoline.de> writes:
>Wenn new _Impl wirft, ist doch __f bzw. my_ws verloren, oder sehe ich den
>Wald vor lauter Bäumen nicht?

  Ich habe hierzu ein Programm (Quelltext folgt unten) geschrieben.

  Es kann (hier unter einem relativ aktuellen GCC) simulieren,
  daß »new _Impl« »bad_alloc« wirft. (Ich weiß nicht, wie
  portabel es ist!)

  Wenn man es nicht werfen läßt, so lautet die Ausgabe:

|now will allocate facet with new
|new 736 bytes at 0x108a248
|now will create new locale with facet
|sized delete 736 bytes at 0x108a248
|closing
|closed
|Everything ok, no memory leak!

  Die Facette wurde beim Auflösen des letzten sie enthaltenden
  Schauplatzes mit aufgelöst.

  Nun wird das Werfen simuliert:

|now will allocate facet with new
|new 736 bytes at 0xdac948
|now will create new locale with facet
|throwing
|Caught bad_alloc.
|Oh no! memory leak detected!

  Mögliche Umgehung:

, Als Argument für den refs-Parameter des Konstruktors
  der Standardklasse "facet" immer 1 zu verwenden.

  Dadurch wird das automatische Auflösen unterdrückt und man
  kann den Speicher dann manuell verwalten, eventuell auch
  mit Hilfe von Schlauzeigern. (Diese Verwaltung könnte aber
  unter Umständen unübersichtlich werden.)

  (Der folgende Quelltext enthält auch einige lange Zeilen mit
  bis zu 103 Zeichen. Ich hoffe, daß diese nicht nach dem
  Versand umbrochen werden.)

#include <iostream>
#include <locale>
#include <sstream>
#include <new>

int trace = 0; /* is this the allocation of the facet to trace? */
/* DO NOT change "trace" here, but only in main1, directly before the allocation! */
void * tmem = nullptr; /* the address of the facet allocated */
int bad = 0; /* do we want to simulate a bad_alloc? */
/* DO NOT change "bad" here, but only in main1, directly before the allocation! */

void *operator new(size_t size)
{ if( bad ){ bad=0; ::std::cout << "throwing\n"; throw ::std::bad_alloc{}; }
  auto mem = malloc(size);
  if( trace ){ ::std::cout << "new " <<  size << " bytes at " << mem << '\n'; tmem = mem; trace = 0; }
  return mem; }

void operator delete( void* ptr )
{ if( ptr==tmem )::std::cout << "delete at " << ptr << '\n';
  free( ptr ); }

void operator delete(void*ptr, std::size_t s)
{ if( ptr==tmem )::std::cout << "sized delete " << s << " bytes at " << ptr << '\n';
  free( ptr );
  if( ptr == tmem )tmem = nullptr; /* ok, it did NOT leak */ }

void check()
{  ::std::cout << (tmem?"Oh no! memory leak detected!\n":"Everything ok, no memory leak!\n"); }

struct csv_whitespace : std::ctype<wchar_t>{};

void main1()
{ { ::std::istringstream iss( "" );
    ::std::cout << "now will allocate facet with new" << '\n';
    trace = 1; /* trace the next allocation */
    auto * my_ws = new csv_whitespace; /* is this allocation leaked? */
    std::cout << "now will create new locale with facet" << '\n';
    bad = 1; /* simulate out-of-memory condition by throwing bad_alloc */
    std::locale( iss.getloc(), my_ws );
    std::cout << "closing\n"; }
   std::cout << "closed\n"; }

int main()
{ try{ main1(); }
  catch( ::std::bad_alloc& ba ){ ::std::cout << "Caught bad_alloc.\n"; }
  check(); }

Back to de.comp.lang.iso-c++ | Previous | NextPrevious in thread | Next in thread | Find similar


Thread

std::locale steht im Wald Udo Steinbach <trashcan@udoline.de> - 2018-12-14 18:32 +0100
  Re: std::locale steht im Wald ram@zedat.fu-berlin.de (Stefan Ram) - 2018-12-15 04:39 +0000
    Re: std::locale steht im Wald Udo Steinbach <trashcan@udoline.de> - 2018-12-16 22:45 +0100

csiph-web