Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

memmove im Construktor

10 views
Skip to first unread message

Robert Hartmann

unread,
Dec 1, 2011, 8:16:42 AM12/1/11
to
Hallo zusammen,

Wenn in einem Konstruktor memmove [1] verwendet wird,
ist es sinnvoll std::bad_alloc zu werfen, wenn memmove
scheitert? Oder besser anders?

Prinzip:

class{
char * b;
size_t s;
};

Test(const char* buffer, size_t size) :
b(NULL), s(0)
{
if((buffer)&&(size)){
this->s=size;
if(!(memmove(this->b, buffer, size)){
//Fehler bei memmove
throw std::bad_alloc;
}
}

}

Gruß Robert

[1] Signatur von memmove:
void * memmove ( void * destination, const void * source, size_t num );

Robert Hartmann

unread,
Dec 2, 2011, 3:09:13 AM12/2/11
to
Am 01.12.2011 14:16, schrieb Robert Hartmann:
> Hallo zusammen,
>
> Wenn in einem Konstruktor memmove [1] verwendet wird,
> ist es sinnvoll std::bad_alloc zu werfen, wenn memmove
> scheitert? Oder besser anders?
>
> Prinzip:

class{
public:
Test(const char* buffer, size_t size)

private:
char * b;
size_t s;
};

Test::Test(const char* buffer, size_t size) :
b(NULL), s(0)
{
if((buffer)&&(size)){
this->s=size;
if(!(memmove(this->b, buffer, size)){
//Fehler bei memmove
throw std::bad_alloc;
}
}
}

So sieht es besser aus :-)

Stefan Reuther

unread,
Dec 1, 2011, 2:39:30 PM12/1/11
to
Robert Hartmann wrote:
> Wenn in einem Konstruktor memmove [1] verwendet wird,
> ist es sinnvoll std::bad_alloc zu werfen, wenn memmove
> scheitert? Oder besser anders?

'memmove' tut kein Scheitern über den Rückgabewert kund, da es, richtig
verwendet, nicht scheitern kann.

# DESCRIPTION
# This function moves LENGTH characters from the block of memory starting
# at `*SRC' to the memory starting at `*DST'. `memmove' reproduces the
# characters correctly at `*DST' even if the two areas overlap.
#
# RETURNS
# The function returns DST as passed.

> Test(const char* buffer, size_t size) :
> b(NULL), s(0)
> {
> if((buffer)&&(size)){
> this->s=size;
> if(!(memmove(this->b, buffer, size)){
> //Fehler bei memmove
> throw std::bad_alloc;

Dieses 'memmove' wird scheitern, und zwar üblicherweise mit eine
Schutzverletzung, da du als Zieladresse NULL angegeben hast.

Was willst du eigentlich mit dem Code bezwecken? Solltest du statt
'memmove' eher 'malloc' meinen, so ist die korrekte Reaktion natürlich
ein 'throw bad_alloc'.


Stefan

Thomas J. Gritzan

unread,
Dec 2, 2011, 11:19:50 AM12/2/11
to
Am 01.12.2011 14:16, schrieb Robert Hartmann:
> Hallo zusammen,
>
> Wenn in einem Konstruktor memmove [1] verwendet wird,
> ist es sinnvoll std::bad_alloc zu werfen, wenn memmove
> scheitert? Oder besser anders?

Kommt auf den Grund des Scheitern an.

> Prinzip:
>
> class{
> char * b;
> size_t s;
> };
>
> Test(const char* buffer, size_t size) :
> b(NULL), s(0)
> {
> if((buffer)&&(size)){
> this->s=size;
> if(!(memmove(this->b, buffer, size)){

Und wo wird der Speicher für b alloziiert?
Wenn du NULL als Ziel für memmove angibst, wird das nicht klappen
(undefiniertes Verhalten).

> //Fehler bei memmove
> throw std::bad_alloc;
> }
> }
>
> }
> [1] Signatur von memmove:
> void * memmove ( void * destination, const void * source, size_t num );

Gruß,
Thomas

Markus Schaaf

unread,
Dec 2, 2011, 6:34:19 AM12/2/11
to
Am 01.12.2011 14:16, schrieb Robert Hartmann:

> Wenn in einem Konstruktor memmove [1] verwendet wird,
> ist es sinnvoll std::bad_alloc zu werfen, wenn memmove
> scheitert? Oder besser anders?

Mir ist nicht bekannt, dass memmove scheitern könnte, noch dass es sowas
explizit signalisieren würde, abgesehen vom immer "möglichen" Problem
ungültiger Pointer. Unabhängig davon ist es sicher nicht richtig, eine
Exception die Speichermangel anzeigt zu benutzen, wenn es sich um kein
solches Problem handelt.

MfG

Robert Hartmann

unread,
Dec 2, 2011, 3:05:55 PM12/2/11
to
Hallo,

Am 01.12.2011 20:39, schrieb Stefan Reuther:
> Robert Hartmann wrote:
>> Wenn in einem Konstruktor memmove [1] verwendet wird,
>> ist es sinnvoll std::bad_alloc zu werfen, wenn memmove
>> scheitert? Oder besser anders?
>
> 'memmove' tut kein Scheitern über den Rückgabewert kund, da es, richtig
> verwendet, nicht scheitern kann.

mhm ...

>
> # DESCRIPTION
> # This function moves LENGTH characters from the block of memory starting
> # at `*SRC' to the memory starting at `*DST'. `memmove' reproduces the
> # characters correctly at `*DST' even if the two areas overlap.
> #
> # RETURNS
> # The function returns DST as passed.
>

Also die einzige Möglichkeit, die ich sehe, dass "even if the two areas
overlap" funktionieren kann, besteht darin, dass memmove eine interne
Kopie von der angegebenen Anzahl N Bytes ab *SRC an eine dritte
_nicht überlappende_ Stelle vornimmt und von dort nach
*DST herüberschaufelt.

Wenn nun aber kein Platz mehr für N Bytes an der dritten Stelle ist,
dann müsste memmove tatsächlich scheitern, auch wenn genügend Platz
bei *DST "hinterlegt" wäre.


>> Test(const char* buffer, size_t size) :
>> b(NULL), s(0)
>> {
>> if((buffer)&&(size)){
>> this->s=size;
>> if(!(memmove(this->b, buffer, size)){
>> //Fehler bei memmove
>> throw std::bad_alloc;
>
> Dieses 'memmove' wird scheitern, und zwar üblicherweise mit eine
> Schutzverletzung, da du als Zieladresse NULL angegeben hast.

Also muss ich vor dem Memmove für b noch genug Speicher
bereit stellen, ich dachte irgendwie, dass Memmove mir den
Speicherbereich, sollte kein gültiger angegeben worden sein,
bereitstellt.


> Was willst du eigentlich mit dem Code bezwecken? Solltest du statt
> 'memmove' eher 'malloc' meinen, so ist die korrekte Reaktion natürlich
> ein 'throw bad_alloc'.
>
>
> Stefan

Gruß Robert

Thomas Maeder

unread,
Dec 3, 2011, 2:36:05 AM12/3/11
to
Robert Hartmann <Robert_...@gmx.net> writes:
>
> Also die einzige Möglichkeit, die ich sehe, dass "even if the two
> areas overlap" funktionieren kann, besteht darin, dass memmove eine
> interne Kopie von der angegebenen Anzahl N Bytes ab *SRC an eine dritte
> _nicht überlappende_ Stelle vornimmt und von dort nach
> *DST herüberschaufelt.

Die einfachere Lösung besteht darin, je nach Art der Überlappung vom
Ende oder vom Anfang her zu kopieren.

--- Posted via news://freenews.netfront.net/ - Complaints to ne...@netfront.net ---

Stefan Reuther

unread,
Dec 3, 2011, 7:01:28 AM12/3/11
to
Robert Hartmann wrote:
> Am 01.12.2011 20:39, schrieb Stefan Reuther:
>> # DESCRIPTION
>> # This function moves LENGTH characters from the block of memory starting
>> # at `*SRC' to the memory starting at `*DST'. `memmove' reproduces the
>> # characters correctly at `*DST' even if the two areas overlap.
>> #
>> # RETURNS
>> # The function returns DST as passed.
>>
> Also die einzige Möglichkeit, die ich sehe, dass "even if the two areas
> overlap" funktionieren kann, besteht darin, dass memmove eine interne
> Kopie von der angegebenen Anzahl N Bytes ab *SRC an eine dritte
> _nicht überlappende_ Stelle vornimmt und von dort nach
> *DST herüberschaufelt.

Nein. Nimm ein Bücherregal mit Platz für 20 Bücher und stelle dort
linksbündig 15 Bücher rein. Jetzt verschiebst du die nach rechts. Und
jetzt wieder nach links. Hast du eine dritte Stelle für die
überlappenden 10 Bücher gebraucht? Das ist memmove :-) Du brauchst nur
ein, zwei Hände, die Bücher halten können. Im Rechner sind das
Prozessorregister.

>>> Test(const char* buffer, size_t size) :
>>> b(NULL), s(0)
>>> {
>>> if((buffer)&&(size)){
>>> this->s=size;
>>> if(!(memmove(this->b, buffer, size)){
>>> //Fehler bei memmove
>>> throw std::bad_alloc;
>>
>> Dieses 'memmove' wird scheitern, und zwar üblicherweise mit eine
>> Schutzverletzung, da du als Zieladresse NULL angegeben hast.
>
> Also muss ich vor dem Memmove für b noch genug Speicher
> bereit stellen, ich dachte irgendwie, dass Memmove mir den
> Speicherbereich, sollte kein gültiger angegeben worden sein,
> bereitstellt.

Ja natürlich musst du den Speicher bereitstellen.

Das siehst du schon am Prototyp: der erste Parameter hat den Typ
'void*'. Da bekommst du nur einen Zeiger rein. Selbst, wenn memmove
Speicher allokieren würde, bekäme es den Zeiger darauf nicht wieder raus.


Stefan

Enrik Berkhan

unread,
Dec 3, 2011, 10:18:19 AM12/3/11
to
Stefan Reuther <stefa...@arcor.de> wrote:
> Das siehst du schon am Prototyp: der erste Parameter hat den Typ
> 'void*'. Da bekommst du nur einen Zeiger rein. Selbst, wenn memmove
> Speicher allokieren würde, bekäme es den Zeiger darauf nicht wieder raus.

Return value?

Enrik

Robert Hartmann

unread,
Dec 16, 2011, 4:08:07 AM12/16/11
to
Am 03.12.2011 13:01, schrieb Stefan Reuther:
> Robert Hartmann wrote:
>> Am 01.12.2011 20:39, schrieb Stefan Reuther:
>>> # DESCRIPTION
>>> # This function moves LENGTH characters from the block of memory starting
>>> # at `*SRC' to the memory starting at `*DST'. `memmove' reproduces the
>>> # characters correctly at `*DST' even if the two areas overlap.
>>> #
>>> # RETURNS
>>> # The function returns DST as passed.
>>>
>> Also die einzige Möglichkeit, die ich sehe, dass "even if the two areas
>> overlap" funktionieren kann, besteht darin, dass memmove eine interne
>> Kopie von der angegebenen Anzahl N Bytes ab *SRC an eine dritte
>> _nicht überlappende_ Stelle vornimmt und von dort nach
>> *DST herüberschaufelt.

Manchmal schaue ich wohl nur in eine Richtung ...

>
> Nein. Nimm ein Bücherregal mit Platz für 20 Bücher und stelle dort
> linksbündig 15 Bücher rein. Jetzt verschiebst du die nach rechts. Und
> jetzt wieder nach links. Hast du eine dritte Stelle für die
> überlappenden 10 Bücher gebraucht? Das ist memmove :-) Du brauchst nur
> ein, zwei Hände, die Bücher halten können. Im Rechner sind das
> Prozessorregister.

Schönes Bild. Danke :-)

Gruß Robert
0 new messages