2010-05-05 12 views
6

Hey Leute. Ich arbeite daran, älteren Code für meinen Job zu reparieren. Es ist derzeit in C++ geschrieben. Sie haben die statische Zuweisung in dynamic konvertiert, aber die memsets/memcmp/memcpy nicht bearbeitet. Dies ist mein erstes Programmierpraktikum, so leer mit meiner Newbe-ähnlichen Frage.Verwenden von MEMSET auf Strukturen in C++

Der folgende Code ist in C, aber ich möchte es in C++ haben (Ich habe gelesen, dass malloc ist keine gute Praxis in C++). Ich habe zwei Szenarien: Zuerst haben wir erstellt. Dann verwenden Sie & f, um mit Null zu füllen. Der zweite ist ein Zeiger * pf. Ich bin nicht sicher, wie pf auf alle 0 wie das vorherige Beispiel in C++ festgelegt werden.

Konnten Sie einfach pf = new foo anstelle von malloc tun und dann memset(pf, 0, sizeof(foo)) anrufen?

struct foo { ... } f; 
memset(&f, 0, sizeof(f)); 

//or 

struct foo { ... } *pf; 
pf = (struct foo*) malloc(sizeof(*pf)); 
memset(pf, 0, sizeof(*pf)); 
+1

Es hängt davon ab, was in foo ist! –

Antwort

8

Ja, aber nur wenn foo ein POD ist. Wenn es virtuelle Funktionen oder irgendetwas anderes C++ ish hat, benutze kein memset, da es über die Interna der struct/class stampfen wird.

Was Sie wahrscheinlich anstelle von memset tun möchten, ist foo ein Konstruktor, um seine Mitglieder explizit zu initialisieren.

Wenn Sie neu verwenden möchten, vergessen Sie nicht das entsprechende Löschen. Noch besser wäre es Shared_ptr zu verwenden :)

+0

Danke Ben. Nachdem ich mir einige andere Dateien angeschaut habe, die sie haben, habe ich festgestellt, dass sie den new-> delete-Weg der Initialisierung mehr verwenden, als einen Konstruktor für die Struktur zu erstellen. Ich werde damit gehen, da sie keine virtuellen Funktionen haben.Danke für die Hilfe. – garry

+0

@garry: wenn 'new' verwendet wird, wird der Konstruktor immer noch aufgerufen. Sie könnten dort seine Attribute initialisieren. –

+3

Kleinere Pedanterie, die in C und C++, auch mit POD-Typen, technisch gesehen undefiniert ist, einfach mit "memset" den Speicher auf Null zu setzen und dann diesen Speicher als etwas anderes als char-Typen und garantiert-no-padding zu lesen -bits '(u) intN_t' Typen. In der Praxis wird Ihre Implementierung dafür sorgen, dass alle 0-Bytes einen Null-Zeiger, eine 0.0-Gleitzahl (wie in IEEE754) usw. bedeuten, aber in der Vergangenheit haben nicht immer alle Implementierungen dies getan. –

2

Ja, das würde funktionieren. Ich denke jedoch nicht, dass Malloc notwendigerweise eine schlechte Übung ist, und ich würde es nicht ändern, nur um es zu ändern. Natürlich sollten Sie sicherstellen, dass Sie die Zuordnungsmechanismen immer richtig zuordnen (new-> delete, malloc-> free usw.).

Sie könnten der Struktur auch einen Konstruktor hinzufügen und diesen zum Initialisieren der Felder verwenden.

3

Können Sie? Ja möglicherweise. Sollten Sie?

Während es wahrscheinlich funktioniert, verlieren Sie den Zustand, den der Konstruktor für Sie erstellt hat. Was passiert, wenn Sie sich entscheiden, eine Unterklasse dieser Struktur zu implementieren? Dann verlieren Sie den Vorteil von wiederverwendbarem Code, den C++ OOP bietet.

Sie sollten stattdessen einen Konstruktor erstellen, der die Mitglieder für Sie initialisiert. Auf diese Weise verwenden Sie diesen Konstruktor, wenn Sie diese Struktur später in der Zeile untergliedern, einfach, um Ihnen beim Erstellen der Unterklassen zu helfen. Dies ist ein kostenloser, sicherer Code! benutze es!

Edit: Der Vorbehalt zu diesem ist, dass, wenn Sie bereits eine riesige Code-Basis haben, ändern Sie es nicht, bis Sie beginnen, die Strukturen subclassing. Es funktioniert so wie es jetzt ist.

2

Sie könnten neue foo (wie der normale Weg in C++) und einen Konstruktor implementieren, die foo initialisiert anstatt Memset.

z.

struct Something 
{ 
    Something() 
     : m_nInt(5) 
    { 

    } 

    int m_nInt; 
}; 

Vergessen Sie auch nicht, wenn Sie neue verwenden löschen rufen, wenn Sie mit dem Objekt fertig sind sonst Sie mit Speicherlecks enden.