Problem: Interne Speicherung von Zahlen in C++

  • Servus, habe ein Problem:

    Ich möchte Elemente aus GF(2^m) platzschonend darstellen. Da es sich dabei ja nur um Polynome mit Elementen aus {0,1} handelt, dachte ich mir, ich allokiere einfach Speicher und lege der Reihe nach die einzelnen Koeffizienten als Bits hinein.

    Ungesetzt habe ich das so (siehe auch Source-Code):

    Ich definiere einen Datentyp, der aus einem Zeiger auf ein array of unsigned char und einem long besteht. Der long-Wert speichert dabei nur die Größe des Array. Dachte nun ich speichere folgendermaßen:

    x^2 + x -> 00000110

    oder

    x^10 + x -> 00000100 00000010
    array[1] array[0]

    Soweit, so gut.

    Jetzt möchte ich aber Daten einspeichern (logisch, sonst machts nicht wirklich Sinn) und müßte daher wissen, wie Zahlen in einem unsigned char abgelegt werden.

    Habe das Ganze mit unsigned int statt char gemacht, ist gelaufen, die Addition (einfaches Xor) hat aber nur Müll ergeben.

    Mit unsigned char kann ich die Klasse (siehe Source) compilieren (Bloodshed Dev-C++), das Programm stürzt aber ab. Nehme ich die Ausgaberoutine heraus, so stürzt es nicht mehr ab.
    Daher die nächste Frage: Was mache ich bei der Verwendung von unsigned char falsch ?? (mit unsigned int statt unsigned char gibt es dieses Problem nicht). Desweiteren stürzt es auch ab, wenn ich einfach Zuweisungen verwende, d.h. wenn ich

    Code
    field a(2);
    a(2) = 2;
    unsigned char x;
    x = a[2]


    verwende.

    Vielen Dank,

    lg. mindless

  • Dir fehlt ein copy constructor, und außerdem das return in field::operator+(). Ganz hab ichs aber auch net zum Laufen gebracht, da schlägt die Komplexität von C++ voll zu.

    Ah ja, das if in field::operator+() ist verdreht, wenn ich das richtig verstehe.

    irgendwer verändert noch den content -- ein Hoch auf deine OOP-Künste! ;)

    [font=verdana,sans-serif]"An über-programmer is likely to be someone who stares quietly into space and then says 'Hmm. I think I've seen something like this before.'" -- John D. Cock[/font]

    opentu.net - freier, unzensierter Informationsaustausch via IRC-Channel!
    Hilfe und Support in Studienangelegenheiten, gemütliches Beisammensein, von und mit Leuten aus dem Informatik-Forum!

  • habs! du musst noch den operator= überladen (copy-constructor hab ich auch noch angehängt):

    [font=verdana,sans-serif]"An über-programmer is likely to be someone who stares quietly into space and then says 'Hmm. I think I've seen something like this before.'" -- John D. Cock[/font]

    opentu.net - freier, unzensierter Informationsaustausch via IRC-Channel!
    Hilfe und Support in Studienangelegenheiten, gemütliches Beisammensein, von und mit Leuten aus dem Informatik-Forum!

  • Zitat von mindless


    Mit unsigned char kann ich die Klasse (siehe Source) compilieren (Bloodshed Dev-C++), das Programm stürzt aber ab. Nehme ich die Ausgaberoutine heraus, so stürzt es nicht mehr ab.

    Daher die nächste Frage: Was mache ich bei der Verwendung von unsigned char falsch ?? (mit unsigned int statt unsigned char gibt es dieses Problem nicht). Desweiteren stürzt es auch ab, wenn ich einfach Zuweisungen verwende, d.h. wenn ich

    tja, ich schaetze mal dein programm macht eine ganze menge unbeabsichtigter sachen.

    erst mal das wichtigste:

    1. es fehlt das return statement

    2. dein gravierendstes problem liegt hier:

    field operator+(field a)

    c++ uebergibt werte per copy ... das heisst das objekt wird fuer die uebergabe als
    parameter a kopiert ... nachdem der parameter a out of scope faellt (beim ende der funktion) wird dieses kopierte objekt destructed ... du deletest also den speicherblock
    auf den unsigned char *content zeigt.

    du greifst aber spaeter noch auf diesen speicheblock zu, weil deine objekte sich den speicherbereich (parameter a ist ja nur eine kopie von objekt b und c ist nur eine kopie des temporaeren namenlosen objekts das du in operator+ zurueckgibst) teilen (weil du keine implementierung des operator= bzw des copyconstructors bereitgestellt hast) -> undefined behaviour

    3. main hat den return type int nicht void

    4. du solltest die c++ standard header verwenden ... also

    #include <cstdio>

    #include <iostream>

    #include <cstdlib>

    dann natuerlich mit namespace std

    5. den default constructor solltest du nicht so stehen lassen.
    entweder verbieten oder eine sinnvolle implementation bereitstellen.

    zusammenfassend:
    copy constuctor hinzufuegen
    operator= hinzufuegen
    operator+ ueberarbeiten

    lg
    zhan

  • Zitat von hal


    irgendwer verändert noch den content -- ein Hoch auf deine OOP-Künste! ;)

    ja, allerdings sehr versteckt. durch die parameteruebergabe per copy gibts 2 pointer die auf den selben memoryblock zeigen. das eine objekt wird beim verlassen der funktion (in diesem fall operator+) destructed.

    ist ein c++ idiom und hat nix mit fehlenden objektorientierungskenntnissen zu tun.
    ein typischer anfaengerfehler.

    lg
    amok

  • Stimmt. Nur überall direkt auf content zugreifen ist trotzdem nicht schön. Dass C++ einfach die internen Memorystrukturen herumkopiert ohne was zu sagen ist auch ein ärgerer Pfusch und zeigt mir wiedermal, warum manche sich weigern, C++ als OOP-Sprache anzuerkennen (allen voran der Erfinder des OOP-Paradigmas) :)

    [font=verdana,sans-serif]"An über-programmer is likely to be someone who stares quietly into space and then says 'Hmm. I think I've seen something like this before.'" -- John D. Cock[/font]

    opentu.net - freier, unzensierter Informationsaustausch via IRC-Channel!
    Hilfe und Support in Studienangelegenheiten, gemütliches Beisammensein, von und mit Leuten aus dem Informatik-Forum!

  • Servus,

    Vielen, vielen Dank für die Antworten (muß gleich vorwegnehmen, daß ich nicht Informatiker bin, daher auch eher schlechte Programmierkentnisse habe, bes. OOP).

    Bin dann auch irgendwann draufgekommen, daß irgendwas mit der Übergabe nicht paßt, habe das dann, mangels besseren Kenntnissen, eher primitiv gelöst:

    Code
    void addition(field &a, field &b, field &c)
    {
    ...addition
    }



    wobei berechnet wird: c = a + b;

    Ist aber irgendwie blöd, da ich auch noch eine Polynommultiplikation brauche, und da kann ich dann nicht a = a + b rechnen, da ja die variable a referenziert wird und daher während der Multiplikation verändert wird. Ist das irgendwie möglich?

    Wenn nicht, wäre infix-notation trotzdem zu bevorzugen, geh es jetzt (analog zu hal's operator):

    Code
    field &operator+(field &a)
    {
    ... addition
    return (this);
    }


    oder werden die Felder trotzdem nur per Referenz übergeben?

    2) Habe wo gelesen, daß die Methoden einer Klasse in externe cpp-Dateien gehören und nur die Header in die h-Datei. Muß das sein (finde es nämlich ein bisserl komisch für eine Klasse 12 Dateien zu erstellen) oder ist es eigentlich wurscht?

    Auf jeden Fal vielen lieben Dank für die raschen und sehr hilfreichen Antworten,
    lg. mindless

  • Zitat von mindless
    Code
    field &operator+(field &a)
    {
    ... addition
    return (this);
    }


    oder werden die Felder trotzdem nur per Referenz übergeben?

    1. this ist in diesem zusammenhang ein pointer auf ein objekt vom typ field. der return type deiner funktion ist aber field& ... du moechtest also return *this; verwenden.

    2. veraendert deine neue implementation den operanden auf der linken seite. das willst du nicht :) c = a + b; // veraendert c und a

    3. liegt dein problem nicht in der addition sondern im memory management des objekts, und du kommst nicht daran vorbei, das zu loesen ohne dass du dir 100e neue probleme schaffst.

    du kannst also durchaus den operator+ ueberladen. aber du musst auch sicherstellen,
    dass die internen datenstrukturen richtig verwaltet werden.

    dazu hast du natuerlich mehrere moeglichkeiten. eine davon hat hal schon gepostet
    (siehe copy constructor und operator= beispiele von hal). natuerlich koenntest du auch andere loesungen verwenden (copy on write, reference counting ...)

    Zitat


    2) Habe wo gelesen, daß die Methoden einer Klasse in externe cpp-Dateien gehören und nur die Header in die h-Datei. Muß das sein (finde es nämlich ein bisserl komisch für eine Klasse 12 Dateien zu erstellen) oder ist es eigentlich wurscht?

    kommt darauf an was du machen willst. wenn du die member function innerhalb der
    klasse definierst ist sie implizit inline.

    wenn sie ausserhalb der klasse definiert ist musst du aufpassen, dass sie nicht
    doppelt definiert wird (dadurch, dass das include file oefters verwendet wird).

    um das verhalten zu erreichen, das du offensichtlich beabsichtigst sollten member functions in eigenen dateien definiert sein und die declaration der classe in einem include file.

  • Zitat von mindless


    2) Habe wo gelesen, daß die Methoden einer Klasse in externe cpp-Dateien gehören und nur die Header in die h-Datei. Muß das sein (finde es nämlich ein bisserl komisch für eine Klasse 12 Dateien zu erstellen) oder ist es eigentlich wurscht?

    du sollst die methoden einer klasse in eine cpp datei zu schreiben.
    d.h. zur jeder headerdatei eine cpp datei. es ist auch durchaus sinnvoll mehrere klassen (welche logisch zusammen gehören, und wo in der regel alle gebraucht werden wenn man eine braucht) in einer header / cpp datei zusammen zu fassen.

  • Zitat von Alex_K

    es ist auch duraus sinnvoll mehrere klassen (welche logisch zusammen gehören, und wo man in der regel alle gebraucht werden wenn man eine braucht) in einer header / cpp datei zusammen zu fassen.


    ja, endlich sagt das auch mal jemand :)

    ich verstehs noch immer nicht, warum man in java fuer jede klasse eine eigene datei anlegen _muss_. Gerade bei sehr kurzen klassen ist das IMHO sehr muehsam.

  • Zitat von Lord Binary

    Wer ist denn das ?

    Alan Kay: "I invented the term Object-Oriented, and I can tell you I did not have C++ in mind."

    (Quelle: smalltalk.org)

    [font=verdana,sans-serif]"An über-programmer is likely to be someone who stares quietly into space and then says 'Hmm. I think I've seen something like this before.'" -- John D. Cock[/font]

    opentu.net - freier, unzensierter Informationsaustausch via IRC-Channel!
    Hilfe und Support in Studienangelegenheiten, gemütliches Beisammensein, von und mit Leuten aus dem Informatik-Forum!

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!