[C++] char* probleem

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Goedenavond,

Ik ben op dit moment bezig met een klein project wat via een plugin informatie vanuit een spel moet doorsturen naar een luisterend socket.
Nou wil ik graag een char laten eindigen met "\n\r", ik heb dit al geprobeerd met:

code:
1
sData [sizeof (sData)] = '\n\r';


maar dat geeft me een 'segmentation fault' als error.

Mijn vraag is nu of iemand me even verder zou kunnen helpen

M'n code:
code:
1
2
3
4
5
6
7
8
9
10
11
12
int CSocket::Send( char *sData )
{
    if (pServer != -1)
    {
                sData [sizeof (sData)] = '\n\r';
        if (send (pServer, sData, strlen (sData), 0) == -1) return -1;
        
        return 1;
    }
    
    return -1;
}

Acties:
  • 0 Henk 'm!

  • Springuin
  • Registratie: Juli 2002
  • Laatst online: 11-09 20:13
C++ is geen java/c#/python, je kunt niet zomaar strings aanelkaar plakken en op geheugenlocaties schrijven waar je niet aan mag komen.

Je moet een nieuwe string aanmaken met ruimte voor de oude en die twee extra karakters en niet de terminating null vergeten:
char * nieuw = malloc(strlen(sData) + 3);
Daar je oude string naartoe kopieren (strcpy), die twee karakters erachteraan plakken (strcat) en dan die nieuwe string versturen. Na het versturen moet je de string vrijgeven met free.

[ Voor 4% gewijzigd door Springuin op 02-04-2011 20:38 ]


Acties:
  • 0 Henk 'm!

  • NATStudent
  • Registratie: Augustus 2008
  • Laatst online: 14-08 13:46
sData is een pointer naar een of meerder chars, maar je hebt zo geen idee naar hoeveel. Als sData bijvoorbeeld een pointer naar 2 chars is, overschrijf je op deze manier geheugen wat niet van jou is. Ook is sizeof (sData) de grootte van een pointer naar char, en dat is niet wat je hier wilt weten geloof ik.

In ieder geval, dit is C++, dus gebruik gewoon de string class.

Acties:
  • 0 Henk 'm!

  • BeerenburgCola
  • Registratie: September 2009
  • Laatst online: 20-09 14:18
Pfff, mijn c/c++ is wat roestig maar ik zie de volgende fouten:

sizeof(sData) is waarschijnlijk de size of (char*) wat de size is van een pointer (8 bytes)
Ook weet je niet of achter de character array nog ruimte is voor "\r\n"

Je kunt ook eerst sData sturen, (zonder afsluitende 0), en daarna "\r\n".

Hopelijk helpt dit een beetje.

Acties:
  • 0 Henk 'm!

  • CyBeR
  • Registratie: September 2001
  • Niet online

CyBeR

💩

wat hierboven gezegd wordt, plus dat de standaard regelafsluiting \r\n is en niet andersom.

All my posts are provided as-is. They come with NO WARRANTY at all.


Acties:
  • 0 Henk 'm!

  • NC83
  • Registratie: Juni 2007
  • Laatst online: 21-08 21:44
BeerenburgCola schreef op zaterdag 02 april 2011 @ 20:39:
Pfff, mijn c/c++ is wat roestig maar ik zie de volgende fouten:

sizeof(sData) is waarschijnlijk de size of (char*) wat de size is van een pointer (8 bytes)
Ook weet je niet of achter de character array nog ruimte is voor "\r\n"

Je kunt ook eerst sData sturen, (zonder afsluitende 0), en daarna "\r\n".

Hopelijk helpt dit een beetje.
De size van een pointer ligt eraan of je op een 32-bits of 64-bits platform werkt, in het eerste geval is het 4 bytes(32 bits) en in het laatste 8 bytes (64 bits).

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


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Goedenavond,

Bedankt voor de vele reacties/informatie. Uiteindelijk heb ik de manier van "Springuin" gebruikt, maar op een of andere manier lekt er geheugen (of iets in die richting) aangezien de verzonden data wordt geprint in de console van de server van het spel.

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int CSocket::Send (char *sData)
{
    if (pServer != -1)
    {
        char *zsData = (char*) malloc (strlen (sData) + 3);
        strcpy (zsData, sData);
        strcat (zsData, "\r\n");
        puts (zsData);
        
        if (send (server, zsData, strlen (zsData), 0) == -1) return -1;
        
        printlog_f ("Socket-send uitgevoerd: %s", zsData );
        free(zsData);
        return 1;
    }
    
    return -1;
}

Acties:
  • 0 Henk 'm!

  • Harrie
  • Registratie: November 2000
  • Nu online

Harrie

NederVlaming

Verwijderd schreef op zaterdag 02 april 2011 @ 21:29:
Goedenavond,

Bedankt voor de vele reacties/informatie. Uiteindelijk heb ik de manier van "Springuin" gebruikt, maar op een of andere manier lekt er geheugen (of iets in die richting) aangezien de verzonden data wordt geprint in de console van de server van het spel.

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int CSocket::Send (char *sData)
{
    if (pServer != -1)
    {
        char *zsData = (char*) malloc (strlen (sData) + 3);
        strcpy (zsData, sData);
        strcat (zsData, "\r\n");
        puts (zsData);
        
        if (send (server, zsData, strlen (zsData), 0) == -1) return -1;
        
        printlog_f ("Socket-send uitgevoerd: %s", zsData );
        free(zsData);
        return 1;
    }
    
    return -1;
}
Moet je de string niet ook free-en als hij niet goed verzonden is? Dus vóór return -1?

Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

CyBeR schreef op zaterdag 02 april 2011 @ 20:40:
wat hierboven gezegd wordt, plus dat de standaard regelafsluiting \r\n is en niet andersom.
Wat mij een beetje verbaast is dat '\n\r' an sich geen foutmelding opleverde. Single quotes om een string heen zouden toch moeten borken? :)

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • CyBeR
  • Registratie: September 2001
  • Niet online

CyBeR

💩

NMe schreef op zaterdag 02 april 2011 @ 21:38:
[...]

Wat mij een beetje verbaast is dat '\n\r' an sich geen foutmelding opleverde. Single quotes om een string heen zouden toch moeten borken? :)
Volgens mij levert dat meestal een warning op, geen error. Ligt aan de compiler denk ik.

All my posts are provided as-is. They come with NO WARRANTY at all.


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Goedenavond,

Blijkbaar zorgde 'puts ()' ervoor dat verstuurde data in de console van de server terecht kwam.
Excuses :+.

Bedankt voor de hulp. Het probleem is verholpen.

Acties:
  • 0 Henk 'm!

  • dragontje124
  • Registratie: Mei 2009
  • Laatst online: 07-09 17:50
Maar zorg er, zoals de rest ook zegt, voor dat ook als het versturen niet goed gaat, free(zsData); uitgevoerd wordt, anders heb je kans op en memory leak.
Als je namelijk iets returned (in dit geval -1), wordt de rest van de functie niet uitgevoerd.

[ Voor 23% gewijzigd door dragontje124 op 02-04-2011 22:29 ]


Acties:
  • 0 Henk 'm!

  • NC83
  • Registratie: Juni 2007
  • Laatst online: 21-08 21:44
Klein puntje in C++ is het afgeraden om malloc en free te gebruiken we hebben daar new en delete voor.

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


Acties:
  • 0 Henk 'm!

  • PrisonerOfPain
  • Registratie: Januari 2003
  • Laatst online: 26-05 17:08
NC83 schreef op zaterdag 02 april 2011 @ 22:42:
Klein puntje in C++ is het afgeraden om malloc en free te gebruiken we hebben daar new en delete voor.
Het word ook afgeraden om char* te gebruiken; daar hebben we std::string voor. Neemt niet weg dat 't in bepaalde situaties nut heeft.

Acties:
  • 0 Henk 'm!

  • NATStudent
  • Registratie: Augustus 2008
  • Laatst online: 14-08 13:46
Als je nou gewoon std::string had gebruikt was het helemaal niet nodig geweest om zelf geheugen te reserveren (en dat dan vervolgens vergeten vrij te maken als je -1 returnet in regel 10).

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
int CSocket::Send( char *sData )
{
    if (pServer != -1)
    {
        std::string stringData(sData);
        stringData += "\r\n";
        if (send (pServer, stringData.c_str(), stringData.length(), 0) == -1)
                return -1;
        
        return 1;
    }
    
    return -1;
}

[ Voor 1% gewijzigd door NATStudent op 03-04-2011 11:52 . Reden: Syntax highlighting ]

Pagina: 1