[C++]Typecasting?

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Hi all,

Ik zit sinds gisteren met een probleempje. Voor een stuk hardware dat we maken gebruiken we een Digi Netwerkmodule om de communicatie af te handelen via een webinterface.
Door een wijziging in deze interface (hex invoer toegevoegd naast decimale invoer) veranderen de functies die de IDE automatisch aanlegt.

Voorheen werd er gewoon een Signed32 als returnvalue verwacht, nu een char-pointer.
Aangezien ik integers uit een register oppik en die wil retourneren, zullen die in een char-pointer gestopt moeten worden, maar om de één of andere reden wil dat niet lukken.

Wat ik kado krijg:
C++:
1
2
3
4
5
6
char *GetVal000a(void) {
    char * theResult;
    
    
    return theResult;
}


Wat ik graag zou willen:
C++:
1
2
3
4
5
6
7
8
9
10
char *GetVal000a(void) {
    char * theResult;
    int regValue;
    
        regValue = getRegister(address);

        theResult = regValue;  // this is where the magic happens...

    return theResult;
}


Dus mijn vraag: Hoe krijg ik de integer in die char-pointer.

Thanks in advance!

Acties:
  • 0 Henk 'm!

  • cenix
  • Registratie: September 2001
  • Laatst online: 16-09 20:24
Je mixed nu een pointer naar een char met een int.
Waar wijst die pointer naar toe?

Zijn een int en een char pointer op jouw hardware eenzelfde grootte?

Acties:
  • 0 Henk 'm!

Verwijderd

Is dit een optie?

C++:
1
2
3
std::stringstream theResult;
theResult << getRegister(address);
return theResult.str();

Acties:
  • 0 Henk 'm!

  • Jaap-Jan
  • Registratie: Februari 2001
  • Laatst online: 23:11
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void toHexString(char* str, int value);

char *GetVal000a(void) {
    char * theResult;
    int regValue;
    
        regValue = getRegister(address);

        toHexString(theResult, regValue);  // this is where the magic happens...

    return theResult;

int toHexString(char* str, int value) {
    return sprintf(str, "%x", value);
}


Zoiets?

Al zou ik het logischer vinden om die hexadeximale strings te converteren naar ints alvorens ze aan GetVal000a() te voeren, aangezien dat minder ruimte inneemt en de computer daar makkelijker mee kan werken. Een hexadecimale string is eigenlijk niets meer dan een bepaalde representatie van een getal en het is makkelijker werken met getallen dan met strings die eigenlijk getallen moeten voorstellen. Met strtol() kun je een string converteren naar een long int (die je wel kunt casten naar een int). :)

[ Voor 26% gewijzigd door Jaap-Jan op 04-09-2009 14:38 ]

| Last.fm | "Mr Bent liked counting. You could trust numbers, except perhaps for pi, but he was working on that in his spare time and it was bound to give in sooner or later." -Terry Pratchett


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Even snel een paar testpogingen ondernomen die tot nu toe nog op niks uitgelopen zijn.

Maar wat ik ter verduidelijking nog even wilde zeggen: Ik wil geen hex waarde retourneren, maar decimale waarden.

Acties:
  • 0 Henk 'm!

  • Mijzelf
  • Registratie: September 2004
  • Niet online
code:
1
2
3
4
5
6
7
8
9
10
char *GetVal000a(void) { 
    char theResult[ 12 ]; 
    int regValue; 
     
    regValue = getRegister(address); 

    itoa( regValue, theResult, 10 ); // this is where the magic happens... 

    return theResult; 
}

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Jij bent de koning! Dat was 't zetje dat ik nodig had...

Wel zelf een itoa moeten copy-pasten, want die zit er niet standaard bij, maar dit lijkt een aardige stap in de goede richting.

Bedankt voor jullie snelle reacties!

Acties:
  • 0 Henk 'm!

  • Mijzelf
  • Registratie: September 2004
  • Niet online
Ik bedenk net dat dit een riskante actie is. De char array staat op stack, en de ruimte wordt weer vrijgegeven als GetVal000a() returnt. Dus als de aanroepende functie stackruimte gebruikt, kan de string al weer overschreven zijn voor hij is gelezen.
Wanneer je programma singlethreaded is (of in elk geval in dit stuk) kun je er een

static char theResult[ 12 ];

van maken.

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Dit gedeelte is idd singlethreaded, dus static zou uitkomst bieden.

Een vraag die hierdoor bij mij opkomt: Valt er iets te zeggen over de kans dat dit scenario - dus dat de string op de stack prematuur overschreven wordt - zich voordoet? En waar hangt dat onder andere vanaf? Met andere woorden, zou ik hier in een grondige test vanzelf tegenaan zijn gelopen of gebeurt dit quasi bij toeval als het product al 3 jaar staat te draaien?

Mijn ervaring hierin is nog vrij beperkt en dit zijn natuurlijk wel dingen om rekening mee te houden als je een stuk software in elkaar draait!

Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 16-09 22:43
Jaap-Jan schreef op vrijdag 04 september 2009 @ 14:27:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void toHexString(char* str, int value);

char *GetVal000a(void) {
    char * theResult;
    int regValue;
    
        regValue = getRegister(address);

        toHexString(theResult, regValue);  // this is where the magic happens...

    return theResult;

int toHexString(char* str, int value) {
    return sprintf(str, "%x", value);
}


Zoiets?
Test om te kijken hoe streng de Digi module is? :P

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • bobo1on1
  • Registratie: Juli 2001
  • Laatst online: 18-05 17:57
Verwijderd schreef op vrijdag 04 september 2009 @ 15:54:
Dit gedeelte is idd singlethreaded, dus static zou uitkomst bieden.

Een vraag die hierdoor bij mij opkomt: Valt er iets te zeggen over de kans dat dit scenario - dus dat de string op de stack prematuur overschreven wordt - zich voordoet? En waar hangt dat onder andere vanaf? Met andere woorden, zou ik hier in een grondige test vanzelf tegenaan zijn gelopen of gebeurt dit quasi bij toeval als het product al 3 jaar staat te draaien?

Mijn ervaring hierin is nog vrij beperkt en dit zijn natuurlijk wel dingen om rekening mee te houden als je een stuk software in elkaar draait!
Naar mijn weten wordt de data overschreven als je genoeg variabelen op de stack zet om in de ruimte te komen waar eerst de char array stond, het kan zijn dat het helemaal nooit gebeurt, het kan ook bijna direct gebeuren nadat je de functie verlaat.

Als je geluk hebt crasht je programma meteen zodat je met een backtrace kunt uitzoeken waar het probleem zit.

Impedance, a measure of opposition to time-varying electric current in an electric circuit.
Not to be confused with impotence.


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
farlane schreef op vrijdag 04 september 2009 @ 16:16:
[...]


Test om te kijken hoe streng de Digi module is? :P
Hier crashete 'ie gewoon op hoor, waarschijnlijk in de toHexString functie. Had zelf ook al zo'n probeersel in elkaar gedraaid met hetzelfde resultaat.

Gaat over deze dingetjes btw, iemand bekend mee hier? Kan altijd van pas komen.
http://www.digi.com/produ...onnectme9210.jsp#overview

Acties:
  • 0 Henk 'm!

  • NC83
  • Registratie: Juni 2007
  • Laatst online: 21-08 21:44
Jaap-Jan schreef op vrijdag 04 september 2009 @ 14:27:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void toHexString(char* str, int value);

char *GetVal000a(void) {
    char * theResult;
    int regValue;
    
        regValue = getRegister(address);

        toHexString(theResult, regValue);  // this is where the magic happens...

    return theResult;

int toHexString(char* str, int value) {
    return sprintf(str, "%x", value);
}
Dit zal een uninitialized variable warning op theResult geven.
Array gebruik zal de volgende warning geven: warning C4172: returning address of local variable or temporary

Static zal werken maar is niet echt netjes aangezien je een pointer terug geeft naar een variable die eigenlijk alleen maar bestaat in de scope van de GetVal000a functie.

Dit werkt ook zoals je weet is bevat een pointer niet meer dan het address naar een variable, je kunt dus gewoon een integer pointer in een char pointer steken. Normaal wordt dit gedaan met een void pointer die geen type heeft waardoor je meteen weet dat je die moet casten.
C++:
1
2
3
4
5
6
7
char *GetVal000a(void) 
{
    int* intValue = new int;
    *intValue = 10;
     
    return (char*)intValue;
}


Hou er rekening mee dat ik hier geheugen alloceer en verwacht dat de aanroepende functie dit zal opruimen om geen memory leak te krijgen.

[ Voor 5% gewijzigd door NC83 op 04-09-2009 16:53 ]

ex-FE Programmer: CMR:DiRT2,DiRT 3, DiRT Showdown, GRID 2, Mad Max


Acties:
  • 0 Henk 'm!

  • Mijzelf
  • Registratie: September 2004
  • Niet online
Verwijderd schreef op vrijdag 04 september 2009 @ 15:54:Een vraag die hierdoor bij mij opkomt: Valt er iets te zeggen over de kans dat dit scenario - dus dat de string op de stack prematuur overschreven wordt - zich voordoet? En waar hangt dat onder andere vanaf? Met andere woorden, zou ik hier in een grondige test vanzelf tegenaan zijn gelopen of gebeurt dit quasi bij toeval als het product al 3 jaar staat te draaien?
Dat hangt ervanaf wat de aanroepende functie(s) doen.
Wanneer overal iets staat als

strcpy( mybuffer, GetVal000a() );

dan gaat het meteen mis, of altijd goed. strcpy gebruikt namelijk een constante hoeveelheid stackruimte. Maar is er iets staat als

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
char *value = GetVal000a();
switch( value[ 0 ] )
{
  case '1':
    {
        int array[ 16 ]; // extra stackruimte gedeclareerd
        for( int i=0; i<16; i++ ) 
            array[ 16 ] = 0; // en overschreven
        break;
    }
  default:
        break;
}


dan treed het probleem op als de string met een '1' begint, en anders niet. Zo zijn er natuurlijk wel een paar triggers te verzinnen die na 3 jaar een probleem veroorzaken.

Onder de streep staat dat het niet netjes/gevaarlijk is om een pointer naar stackruimte te retourneren. Zelfs het strcpy voorbeeld kan na 3 jaar ontploffen als de dll die strcpy bevat wordt vervangen.

[ Voor 10% gewijzigd door Mijzelf op 04-09-2009 18:32 ]


Acties:
  • 0 Henk 'm!

  • Jaap-Jan
  • Registratie: Februari 2001
  • Laatst online: 23:11
farlane schreef op vrijdag 04 september 2009 @ 16:16:
[...]


Test om te kijken hoe streng de Digi module is? :P
Blunder, theResult is niet geïnitialiseerd. :$

| Last.fm | "Mr Bent liked counting. You could trust numbers, except perhaps for pi, but he was working on that in his spare time and it was bound to give in sooner or later." -Terry Pratchett


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 16-09 22:43
Jaap-Jan schreef op vrijdag 04 september 2009 @ 18:55:
Blunder, theResult is niet geïnitialiseerd. :$
;)

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.

Pagina: 1