Toon posts:

[C++]Foutmelding bij return

Pagina: 1
Acties:

Verwijderd

Topicstarter
Bij het uitvoeren van 'code part 2' in de main() functie loopt het programma vast na het pause commando. Als je dat stukje code comment, en dus enkel 'code part 1' start dan krijg je geen error.

Anders gezegd:
Als de functie StringToReversedBin() een string meekrijgt die groter is dan 8 byte, dan krijgt het programma problemen.

Weet er iemand een oplossing?

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <vector.h>

char *StringToReversedBin(char *data)
{
    char oneByte[8]="";
    double current;
    int counter;
    char *resultString;
    int resultlength = (strlen(data)*8);
    int bitpos;

    resultString = new char[resultlength]; // make a new string to store vector in
    memset(resultString, 0, resultlength); // allocate memory

    for (int i=0; i<strlen(data); i++)              // run through all characters
    {
        current = data[i];                          // current character value
        counter = 0;                                // this value will be used to add zero's at the end
        do
        {
            bitpos = (i*8)+counter;
            counter++;
            oneByte[i] = (int)fmod(current,2);      // divide by 2 and find rest
            if (oneByte[i]==0)
                resultString[bitpos] = '0';         // add bit to vector
            else
                resultString[bitpos] = '1';         // add bit to vector            
            current = (current-oneByte[i])/2;
        } while (current>0);                        // loop until division results 0
        for (int j=0; j<(8-counter); j++)           // add zero's at end
            resultString[bitpos+j+1] = '0';
    }
    free(oneByte);
    printf("Return value function, befor return:\n%s\n", resultString);
    return resultString;  
}

int main()
{
    //<-- code part 1
    char *data = "12345678";
    data = StringToReversedBin(data);
    printf("Returned value:\n%s\n\n", data);
    //--> end code part 1

    //<-- code part 2 
    data = "123456789";
    data = StringToReversedBin(data);
    printf("Returned value:\n%s\n\n", data);
    //--> end code part 2

    system("PAUSE");
    free(data); 
    return 0;
}



[edit] Mijn excuses, ik ben [c++] in het topic vergeten vermelden *schaam*

[ Voor 20% gewijzigd door Verwijderd op 20-03-2003 19:46 ]


  • madwizard
  • Registratie: Juli 2002
  • Laatst online: 26-10-2024

madwizard

Missionary to the word of ska

Bij mij crasht het programma zelfs al bij part1. Je haalt wat vreemde dingen uit in je code, 'new' bijvoorbeeld is C++, en moet worden gecombineerd met delete dan wel delete[], niet met 'free' (C). Bovendien hoef je lokale arrays niet te free-en. Ook snap ik niet waarom je zo ingewikkeld doet met een karakter gecast naar een double om die vervolgens weer te delen etc.
Je kunt beter nog een keer je algoritme herzien, het kan namelijk veel makkelijker met wat boolean logic.
Een 'echte C++' manier om dit te doen is bijvoorbeeld zo (als ik goed begrepen heb wat je wilt):
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
string StringToReversedBin2(const string &src)
{
    string res;
    res.resize(src.size()*8);
    string::iterator itOut = res.begin();
    string::const_iterator it;
    for (it=src.begin();it!=src.end();it++)
    {
        char c = (*it);
        for (int i=0;i<8;i++,c>>=1)
            *itOut++ = '0' + (c&1);
    }
    return res;
}
int main()
{
    cout << StringToReversedBin2("1234") << endl;
    cout << StringToReversedBin2("1234567890ABCDEFGHI") << endl;
}

www.madwizard.org


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 21-08 17:14
Je roept free() aan op een pointer die niet van malloc komt. Je hebt pech dat het de eerste keer niet klapt.

Tip: Lees hoe std::string werkt. In C++ heb je free() niet nodig, dat zit er alleen vanwege de backwards compatibility met C.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


Verwijderd

Topicstarter
Jullie zijn beide heel erg bedankt! Ik ga zometeen de code herzien (en de code van madwizard eens bekijken). Ik ben nogal een n00b ivm free, malloc en delete, vandaar die dommigheden.

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 22-08 01:56
Leg ons eens uit wat jij denkt dat memset doet? En waarom vind je dat je wel de ene stack variabele (oneByte) moet free'en en de anderen niet?

[ Voor 51% gewijzigd door Soultaker op 20-03-2003 21:13 ]


Verwijderd

Topicstarter
madwizard schreef op 20 March 2003 @ 21:08:
Bij mij crasht het programma zelfs al bij part1. Je haalt wat vreemde dingen uit in je code, 'new' bijvoorbeeld is C++, en moet worden gecombineerd met delete dan wel delete[], niet met 'free' (C). Bovendien hoef je lokale arrays niet te free-en. Ook snap ik niet waarom je zo ingewikkeld doet met een karakter gecast naar een double om die vervolgens weer te delen etc.
Je kunt beter nog een keer je algoritme herzien, het kan namelijk veel makkelijker met wat boolean logic.
Een 'echte C++' manier om dit te doen is bijvoorbeeld zo (als ik goed begrepen heb wat je wilt):
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
string StringToReversedBin2(const string &src)
{
    string res;
    res.resize(src.size()*8);
    string::iterator itOut = res.begin();
    string::const_iterator it;
    for (it=src.begin();it!=src.end();it++)
    {
        char c = (*it);
        for (int i=0;i<8;i++,c>>=1)
            *itOut++ = '0' + (c&1);
    }
    return res;
}
int main()
{
    cout << StringToReversedBin2("1234") << endl;
    cout << StringToReversedBin2("1234567890ABCDEFGHI") << endl;
}
hoe kan je het best die string naar een char* omzetten(ik vond meerdere mogelijkheden maar vraag me af wat programmalogisch het beste is)? kan ik een sprintf en dergelijke op een string toepassen? mag ik je in de credits van m'n game plaatsen(zo ja: onder welke nick/naam?)?

Verwijderd

Topicstarter
Soultaker schreef op 20 maart 2003 @ 21:12:
Leg ons eens uit wat jij denkt dat memset doet? En waarom vind je dat je wel de ene stack variabele (oneByte) moet free'en en de anderen niet?
memset alloceerd volgens mij gewoon geheugen voor die char*. en ik denk dat ik resultString niet mag free'en omdat dat de returnwaarde is vr de functie. *voelt zich n00b*

tis de eerste keer dat ik eigenlijk met strings begin te prutsen, vroeger had ik enkel wat arrays nodig en printf/scanf variaties, vandaar dat ik nu in de knoop sla


[edit] Bedankt aan diegene die de [c++] tag toevoegde in de topictitel

[ Voor 8% gewijzigd door Verwijderd op 20-03-2003 21:30 ]


  • Glimi
  • Registratie: Augustus 2000
  • Niet online

Glimi

Designer Drugs

(overleden)
Verwijderd schreef op 20 maart 2003 @ 21:27:
hoe kan je het best die string naar een char* omzetten(ik vond meerdere mogelijkheden maar vraag me af wat programmalogisch het beste is)? (..)
Zover ik weet is c_str() de enige die een char[] let's make that const char* teruggeeft.
std::string::iterator en [] kun je gebruiken om er zelf een te bouwen, maar dat lijkt me overbodig :)

[ Voor 22% gewijzigd door Glimi op 20-03-2003 22:33 ]


Verwijderd

Topicstarter
Glimi schreef op 20 March 2003 @ 21:33:

[...]
Zover ik weet is c_str() de enige die een char[] teruggeeft.
std::string::iterator en [] kun je gebruiken om er zelf een te bouwen, maar dat lijkt me overbodig :)
die c_str() wordt blijkbaar niet ondersteund door mingw (tenzij het uit een andere library dan string of string.h komt)

  • madwizard
  • Registratie: Juli 2002
  • Laatst online: 26-10-2024

madwizard

Missionary to the word of ska

Verwijderd schreef op 20 March 2003 @ 21:27
hoe kan je het best die string naar een char* omzetten(ik vond meerdere mogelijkheden maar vraag me af wat programmalogisch het beste is)?
De officiele methode is:
C++:
1
const char * pc = str.c_str();
kan ik een sprintf en dergelijke op een string toepassen?
sprintf gebruikt alleen char*-style strings maar std::string's kun je dus wel omzetten naar char pointers. Maar ook sprintf zit er alleen voor backwards compatibility. De C++ manier om strings op te bouwen/formatteren is met string streams (of direct iostreams):
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include <sstream>
using namespace std;
void main()
{
    int i = 1234;
    const char *pc = "koe";
    string str = "fiets";
    // Direct naar stdout:
    cout << "i = " << i << " of 0x" << 
         hex << i << ", pc: " << pc <<
         ", str: " << str << endl;

    // Met stringstream naar string
    ostringstream sstream;
    sstream << "i = " << i << " of 0x" << 
            hex << i << ", pc: " << pc <<
            ", str: " << str << endl;
    // sstream.str() is een std::string met de geformatteerde tekst
    // sstream.str().c_str() is weer een char* daarnaar toe
}

Dit staat vast wel ergens uitgelegd in goede C++ tutorials.
mag ik je in de credits van m'n game plaatsen(zo ja: onder welke nick/naam?)?
Zoveel moeite was het ook niet hoor :) maar van mij mag je, doe maar als MadWizard.

[ Voor 40% gewijzigd door madwizard op 20-03-2003 21:44 ]

www.madwizard.org


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22-08 13:19

.oisyn

Moderator Devschuur®

Demotivational Speaker

Glimi schreef op 20 March 2003 @ 21:33:
[nohtml]
[...]
[/nohtml] Zover ik weet is c_str() de enige die een char[] teruggeeft.


c_str () geeft overigens const char * terug, maar er is ook nog data (), die ook een const char * teruggeeft. Het verschil zit m in het feit dat c_str () een '\0' achter de string plakt zodat ie compatible is met de asciiz string :)

en kenvh:
bij malloc () -> free ()
bij new ... -> delete
bij new ...[x] -> delete[]

en verder hoef je malloc () (en dus free ()) totaal niet te gebruiken in C++ programma's :)

[ Voor 19% gewijzigd door .oisyn op 20-03-2003 22:04 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

Topicstarter
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
char *StringToReversedBin(const string &src) 
{ 
    string res;
    res.resize(src.size()*8);
    string::iterator itOut = res.begin();
    string::const_iterator it;
    for (it=src.begin();it!=src.end();it++)
    {
        char c = (*it);
        for (int i=0;i<8;i++,c>>=1)
            *itOut++ = '0' + (c&1);
    }
    ostringstream dataStream;
    dataStream << res;
    return dataStream.c_str();
}


Dit zou normaal gezien moeten werken, maar de compiler herkent c_str() niet :(
59 E:\C__~1\CRYPTO~1\main.cpp
no matching function for call to `ostringstream::c_str ()'

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 22-08 01:56
Verwijderd schreef op 20 March 2003 @ 21:30:
memset alloceerd volgens mij gewoon geheugen voor die char*.
Helaas; beter in de handleiding kijken. ;) Memset plaatst bepaalde waarden in het geheugen (zoals de naam al doet vermoeden). Je vult dus gewoon de array (die al met new alloceerd is) met nullen. Niet fout, maar je hebt er niets aan (vooral niet als je daarna de inhoud van je array toch weer gaat overschrijven)

Er gaat sowieso van alles fout doordat je je character array niet afsluit met een 0-karakter.
en ik denk dat ik resultString niet mag free'en omdat dat de returnwaarde is vr de functie.
Dat is ook nog eens zo ja, maar ik doel op 't feit dat je een statisch gealloceerde array (oneByte) probeert vrij te geven (wat niet hoeft/kan: dat gebeurt al 'automatisch' doordat de stack space herbruikt wordt).
tis de eerste keer dat ik eigenlijk met strings begin te prutsen, vroeger had ik enkel wat arrays nodig en printf/scanf variaties, vandaar dat ik nu in de knoop sla
Probeer dan gebruik te maken van C++ strings, waar mogelijk. Dat scheelt een boel hoofdbrekens.

Verwijderd

Topicstarter
Soultaker schreef op 20 maart 2003 @ 22:01:
[...]

Helaas; beter in de handleiding kijken. ;) Memset plaatst bepaalde waarden in het geheugen (zoals de naam al doet vermoeden). Je vult dus gewoon de array (die al met new alloceerd is) met nullen. Niet fout, maar je hebt er niets aan (vooral niet als je daarna de inhoud van je array toch weer gaat overschrijven)

Er gaat sowieso van alles fout doordat je je character array niet afsluit met een 0-karakter.


[...]

Dat is ook nog eens zo ja, maar ik doel op 't feit dat je een statisch gealloceerde array (oneByte) probeert vrij te geven (wat niet hoeft/kan: dat gebeurt al 'automatisch' doordat de stack space herbruikt wordt).


[...]


Probeer dan gebruik te maken van C++ strings, waar mogelijk. Dat scheelt een boel hoofdbrekens.
Ik ga strings zeker eens bekijken. Die streaming functies zijn heel eenvoudig. Op school kregen we bvb nooit uitleg over cin/cout, terwijl die veel eenvoudiger zijn dan bijvoorbeeld de printf en scanf varianten.
/me curses his former teacher

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22-08 13:19

.oisyn

Moderator Devschuur®

Demotivational Speaker

Verwijderd schreef op 20 March 2003 @ 22:00:
Dit zou normaal gezien moeten werken, maar de compiler herkent c_str() niet :(


bij een ostringstream is het str (), die geeft een std::string terug
op die std::string moet je weer c_str () aanroepen om een c-style null-terminated string terug te krijgen

en check ook even mijn edit in m'n vorige post :)

[ Voor 40% gewijzigd door .oisyn op 20-03-2003 22:06 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Glimi
  • Registratie: Augustus 2000
  • Niet online

Glimi

Designer Drugs

(overleden)
.oisyn schreef op 20 maart 2003 @ 21:59:
c_str () geeft overigens const char * terug, maar er is ook nog data (), die ook een const char * teruggeeft. Het verschil zit m in het feit dat c_str () een '\0' achter de string plakt zodat ie compatible is met de asciiz string :)

offtopic:
Mjah ik las het net, maar was te lui om m'n bericht aan te passen.
Eigenlijk is het een geinstantieerde template van basic_string met char, waarvoor string een typedef is, kwam ik net achter :)


[topicstarter]
Je bent nu c_str() aan het aanroepen op een stream, niet op een string zelf :)

Verwijderd

Topicstarter
.oisyn schreef op 20 maart 2003 @ 21:59:

[...]


c_str () geeft overigens const char * terug, maar er is ook nog data (), die ook een const char * teruggeeft. Het verschil zit m in het feit dat c_str () een '\0' achter de string plakt zodat ie compatible is met de asciiz string :)

en kenvh:
bij malloc () -> free ()
bij new ... -> delete
bij new ...[x] -> delete[]

en verder hoef je malloc () (en dus free ()) totaal niet te gebruiken in C++ programma's :)
_/-\o_

Verwijderd

Topicstarter
ik zou mezelf moeten verbieden om na 5u smiddags te coden :$ *feels dumb*

[edit] maar gelukkig snap ik het geheel nu ongeveer. morgen (na een beetje welverdiende slaap - ik code al de hele dag door) ga ik me verdiepen op streams en strings.

[ Voor 54% gewijzigd door Verwijderd op 20-03-2003 22:19 ]


Verwijderd

Topicstarter
Natuurlijk heb ik het niet kunnen laten om verder te werken aan de rest van de code...

Het algoritme geeft een basis die ik ga gebruiken om gegevens te beveiligen. Daarom dat ik alles in binair formaat wil zodat ik bits kan invoegen, shiften en dergelijke. Dit geheel komt in een groter project terecht (threaded server) en die server zal dienst doen voor m'n game. Iedereen die geholpen heeft is heel erg bedankt!

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <math.h>


string StringToReversedBin(const string &src) 
{ 
    string res;
    res.resize(src.size()*8);
    string::iterator itOut = res.begin();
    string::const_iterator it;
    for (it=src.begin(); it!=src.end(); it++)
    {
        char c = (*it);
        for (int i=0; i<8; i++,c>>=1)
            *itOut++ = '0' + (c&1);
    }
    return res;
}

string ReversedBinToString(const string &src) 
{ 
    string res;
    res.resize(src.size()/8);
    string::iterator itOut = res.begin();
    string::const_iterator it;
    int charvalue = 0;
    int place = 0;
    for (it=src.begin();it!=src.end();it++)
    {
        place++;
        if (place == 9)
        {
            char charout = charvalue;
            *itOut++ = charout;
            charvalue = 0;
            place = 1;
        }

        char c = (*it);

        if (c == '1')
            charvalue += (int)pow(2,place-1);
    }
    char charout = charvalue;
    *itOut++ = charout;
    return res;
}

string CL_Encrypt(string data, string password)
{
    return StringToReversedBin(data);
}

string CL_Decrypt(string data, string password)
{
    return ReversedBinToString(data);
}

int main()
{
    string data = "This is a test";
    cout << "Original data: " << endl << data << endl << endl;

    data = CL_Encrypt(data, "test");
    cout << "Encrypted data: " << endl << data << endl << endl;

    data = CL_Decrypt(data, "test");
    cout << "Decrypted data: " << endl << data << endl << endl;

    system("PAUSE");
    return 0;
}

[ Voor 18% gewijzigd door Verwijderd op 20-03-2003 23:19 ]


  • madwizard
  • Registratie: Juli 2002
  • Laatst online: 26-10-2024

madwizard

Missionary to the word of ska

Voor integers:
pow(2,x) == 1 << x
Een shift is een stuk efficienter dan een pow, zowieso kan de hele functie wel wat korter:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
string ReversedBinToString(const string &src)
{  
    string res; 
    int nChars = src.size() / 8;
    res.resize(nChars); 
    string::iterator itOut = res.begin(); 
    string::const_iterator it = src.begin(); 
    for (int i=0;i<nChars;i++) 
    { 
        unsigned char c = 0;
        for (int j=0;j<8;j++)
            c = (c>>1) | (*it++ & 1) << 7;
        *itOut++ = c;
    } 
    return res; 
}

Bovenstaande code gaat er wel vanuit dat de source string ook echt uit 0en en 1en bestaat, dus geen 'a' ofzo, geeft een ongedefinieerd resultaat (en dat je compileert voor een OS met de ansi karakter set maar dat zal wel :) ). Het idee is dat het karakter '0' gelijk is aan 0x30, en '1' aan 0x31. Als je de laatste bit AND (*it++ & 1) krijg je dus 0 voor '0' en 1 voor '1'. De loop met int j doet steeds 1 karakter, waarbij begonnen wordt met 0 (unsigned char, anders gaat de right shift verkeerd). Voor elke bit wordt eerst het huidige resultaat 1 naar rechts geschoven (>>1) en daarna de 0 of 1 helemaal links (<<7) erbij geORt.

www.madwizard.org


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

madwizard schreef op 20 March 2003 @ 21:08:
Bij mij crasht het programma zelfs al bij part1. Je haalt wat vreemde dingen uit in je code, 'new' bijvoorbeeld is C++, en moet worden gecombineerd met delete dan wel delete[], niet met 'free' (C).
Ja erg prettig dat kenvh de moeite blijkbaar neemt om gegeven hulp te lezen en te gebruiken, nav. dit topic waarin precies hetzelfde gebeurde.

Ik citeer uit de mail die ik hem maandag 17 maart heb verstuurd in de hoop hulpvaardig te zijn:
Ik gok dat je probleem zit in het feit dat je in die thread een char* pChar aanmaakt met new[] en deze vervolgens vrijgeeft met free. Die zijn totaal incompatibel.
Fijn als je er 3 dagen later achterkomt hoe goed je hulp wordt gebruikt en de geboden kennis wordt opgeslagen voor later gebruik... :r :| :r :|

Professionele website nodig?


Verwijderd

Topicstarter
curry684 schreef op 21 March 2003 @ 00:42:
[...]

Fijn als je er 3 dagen later achterkomt hoe goed je hulp wordt gebruikt en de geboden kennis wordt opgeslagen voor later gebruik... :r :| :r :|
Sorry dude, ik was gisteren-avond gewoon heel slecht bezig. Waarschijnlijk dr vermoeidheid (kheb de laatste dagen niks anders gedaan dan gecode).
*schaam*

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

Verwijderd schreef op 21 March 2003 @ 13:48:
[...]
Sorry dude, ik was gisteren-avond gewoon heel slecht bezig. Waarschijnlijk dr vermoeidheid (kheb de laatste dagen niks anders gedaan dan gecode).
*schaam*
Naja komt iig eerlijk uit voor je fouten... kwerd beetje link toen ik zag dat je exact op het punt fout ging waar ik je vandeweek op had gewezen.

Zand erover ;)

Professionele website nodig?


Verwijderd

Topicstarter
curry684 schreef op 21 March 2003 @ 18:09:
[...]

Naja komt iig eerlijk uit voor je fouten... kwerd beetje link toen ik zag dat je exact op het punt fout ging waar ik je vandeweek op had gewezen.

Zand erover ;)
Thanks :) kga het zeker niet vergeten nu. *voelt zich btje dom*
't Belangrijkste is dat ik wat bijleerd denk ik :)
Pagina: 1