1. Dashboard
  2. Forum
    1. Unerledigte Themen
  3. Mitglieder
    1. Letzte Aktivitäten
    2. Benutzer online
    3. Team-Mitglieder
    4. Trophäen
    5. Mitgliedersuche
  4. Tutorial Bereich
  • Anmelden
  • Registrieren
  • Suche
Dieses Thema
  • Alles
  • Dieses Thema
  • Dieses Forum
  • Seiten
  • Forum
  • Lexikon
  • Erweiterte Suche
  1. Informatik Forum
  2. Webmaster & Internet
  3. Entwicklung

Problem: Interne Speicherung von Zahlen in C++

    • Frage
  • mindless
  • 12. August 2004 um 11:01
  • Unerledigt
  • mindless
    5
    mindless
    Mitglied
    Punkte
    250
    Beiträge
    44
    • 12. August 2004 um 11:01
    • #1

    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

  • hal
    32
    hal
    Mitglied
    Reaktionen
    52
    Punkte
    11.122
    Beiträge
    2.208
    • 12. August 2004 um 14:25
    • #2

    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.

    Code
    0xbfffef10: create 0x500140
    0xbfffef20: create 0x500150
    0xbfffef30: create 0x500160
    0xbfffef50: copy 0x500170
    0xbfffef40: create 0x500180
    0xbfffef40: delete 0x500180
    0xbfffef50: delete 0x500170
    
    
    0xbfffef30: delete 0x500180
    *** malloc[25204]: Deallocation of a pointer not malloced: 0x500180; This could be a double free(), or free() called with the middle of an allocated block; Try setting environment variable MallocHelp to see tools to help debug
    0xbfffef20: delete 0x500150
    0xbfffef10: delete 0x500140
    Alles anzeigen

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

    [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!

  • hal
    32
    hal
    Mitglied
    Reaktionen
    52
    Punkte
    11.122
    Beiträge
    2.208
    • 12. August 2004 um 14:39
    • #3

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

    Code
    const field &operator=(const field &a)
        {
            if(size != a.size) {
                delete [] content;
                size = a.size;
                content = new unsigned char [size];
            }
            memcpy(content,a.content,size);
            return a;
        }
        field(field &copy)
        {
            size = copy.size;
            content = new unsigned char [size];
            memcpy(content,copy.content,size);
        }
    Alles anzeigen

    [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!

  • amok
    5
    amok
    Mitglied
    Punkte
    190
    Beiträge
    38
    • 12. August 2004 um 14:41
    • #4
    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:

    Code
    field operator+(field a)
    
    
    {
    
    
      long i,j;
    
    
      if (size > a.size)
    
    
      {j = size;}
    
    
      else
    
    
      {j = a.size;}
    
    
    
    
      field tmp(j);
    
    
      
      for (i=0; i<j; i++) {tmp.content[i] = content[i]^a.content[i];}
    
    
    }
    Alles anzeigen

    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

  • amok
    5
    amok
    Mitglied
    Punkte
    190
    Beiträge
    38
    • 12. August 2004 um 14:49
    • #5
    Zitat von hal


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

    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

  • hal
    32
    hal
    Mitglied
    Reaktionen
    52
    Punkte
    11.122
    Beiträge
    2.208
    • 12. August 2004 um 15:03
    • #6

    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!

  • mindless
    5
    mindless
    Mitglied
    Punkte
    250
    Beiträge
    44
    • 12. August 2004 um 15:45
    • #7

    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

  • amok
    5
    amok
    Mitglied
    Punkte
    190
    Beiträge
    38
    • 12. August 2004 um 16:14
    • #8
    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.

  • mindless
    5
    mindless
    Mitglied
    Punkte
    250
    Beiträge
    44
    • 12. August 2004 um 20:05
    • #9

    Vielen Dank für die Hilfe,

    lg. und schönen Abend noch

    mindless

  • Alex_K
    15
    Alex_K
    Mitglied
    Reaktionen
    10
    Punkte
    2.465
    Beiträge
    487
    • 12. August 2004 um 23:04
    • #10
    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.

    Total world domination is proceeding as planned.

  • MaxAuthority
    17
    MaxAuthority
    Gewinner des Desktop-Contest 2002
    Reaktionen
    5
    Punkte
    3.165
    Beiträge
    626
    • 13. August 2004 um 06:33
    • #11
    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.

    http://vimperator.org - Make Firefox behave like Vim

  • Lord Binary
    18
    Lord Binary
    Mitglied
    Reaktionen
    11
    Punkte
    3.301
    Beiträge
    647
    • 13. August 2004 um 08:43
    • #12
    Zitat
    Zitat

    (allen voran der Erfinder des OOP-Paradigmas)

    Wer ist denn das ?


    Trading for a living [equities,futures,forex]

  • hal
    32
    hal
    Mitglied
    Reaktionen
    52
    Punkte
    11.122
    Beiträge
    2.208
    • 13. August 2004 um 16:16
    • #13
    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!

  • Maximilian Rupp 27. Dezember 2024 um 12:06

    Hat das Thema aus dem Forum Programmieren nach Entwicklung verschoben.

Jetzt mitmachen!

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

Benutzerkonto erstellen Anmelden

Benutzer online in diesem Thema

  • 1 Besucher

Rechtliches

Impressum

Datenschutzerklärung