[C] character array geeft segmentation error na bzero()

Pagina: 1
Acties:

  • Odin
  • Registratie: November 2002
  • Laatst online: 30-07 10:54

Odin

¯¯¯¯¯

Topicstarter
ik maak een functie die simpelweg een meegegeven c-string (buffer) over een socket verstuurd, maar waarna write() is uitgevoerd en ik de buffer leeg wil maken met bzero krijg ik een segmentation fault.
Ik heb al heel veel geprobeerd om het op te lossen, bv 2 aparte buffers etc. Het vreemde vind ik dat ik de code letterlijk heb gekopieerd van een voorbeeld programma die hier te vinden is.

mijn functie:
code:
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
int vlc_message(char *buffer) {

    int sockfd,n;
    int portno = 21000;
    struct sockaddr_in serv_addr;
    struct hostent *server;

    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0)
        error("ERROR opening socket");

    server = gethostbyname("127.0.0.1");

    bzero((char *) &serv_addr, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    bcopy((char *)server->h_addr,
         (char *)&serv_addr.sin_addr.s_addr,
         server->h_length);
    serv_addr.sin_port = htons(portno);

    if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)
        error("ERROR connecting");

    n = write(sockfd,buffer,strlen(buffer));

    if (n < 0)
         error("ERROR writing to socket");

    bzero(buffer,256);

    n = read(sockfd,buffer,255);

    if (n < 0)
         error("ERROR reading from socket");

    close(sockfd);

    return SUCCES;
}

  • LazySod
  • Registratie: Augustus 2003
  • Laatst online: 28-11 13:28

LazySod

Scumbag with a mission

Is de buffer waarmee je de functie aanroept ook wel degelijk (op zijn minst) 256 karakters groot?

Proof is the idol before whom the pure mathematician tortures himself. (Sir Arthur Eddington)


  • Soultaker
  • Registratie: September 2000
  • Nu online
En is het wel writeable memory? Als je in C je functie zo aanroept:
C:
1
vlc_message("Bericht hier!");

Dan is je buffer ten eerste niet groot genoeg, en ten tweede wordt 'ie in read-only memory geplaatst (ondanks dat het type char* is, vanwege backward compatibility met C programma's toen C nog geen const kende).

Sowieso is het raar om de uitvoer in dezelfde buffer te doen als de invoer. Ik zou het zo schrijven:
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
int vlc_command(const char *command, char *response, int response_len)
{
    // ..
    write(fd, command, strlen(command));
    // ...
    if(response_len > 0)
    {
        int bytes_read = read(fd, response, response_len - 1);
        if(bytes_read >= 0)
            response[bytes_read] = '\0';
        else
            // .. handle error
    }
}

Invoer en uitvoer gaan dus over verschillende buffers. Je werkt dan alleen met C-strings (dus binary data is niet mogelijk), maar dat lijkt ook je bedoeling. De caller is er voor verantwoordlijk een buffer voor het antwoord te alloceren (en die groot genoeg te maken). Het hangt een beetje van je toepassing af of het erg is dat berichten afgekapt kunnen worden.

[ Voor 10% gewijzigd door Soultaker op 06-05-2007 18:07 ]


  • Odin
  • Registratie: November 2002
  • Laatst online: 30-07 10:54

Odin

¯¯¯¯¯

Topicstarter
Soultaker schreef op zondag 06 mei 2007 @ 17:59:
En is het wel writeable memory? Als je in C je functie zo aanroept:
C:
1
vlc_message("Bericht hier!");

Dan is je buffer ten eerste niet groot genoeg, en ten tweede wordt 'ie in read-only memory geplaatst (ondanks dat het type char* is, vanwege backward compatibility met C programma's toen C nog geen const kende).

Sowieso is het raar om de uitvoer in dezelfde buffer te doen als de invoer. Ik zou het zo schrijven:
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
int vlc_command(const char *command, char *response, int response_len)
{
    // ..
    write(fd, command, strlen(command));
    // ...
    if(response_len > 0)
    {
        int bytes_read = read(fd, response, response_len - 1);
        if(bytes_read >= 0)
            response[bytes_read] = '\0';
        else
            // .. handle error
    }
}

Invoer en uitvoer gaan dus over verschillende buffers. Je werkt dan alleen met C-strings (dus binary data is niet mogelijk), maar dat lijkt ook je bedoeling. De caller is er voor verantwoordlijk een buffer voor het antwoord te alloceren (en die groot genoeg te maken). Het hangt een beetje van je toepassing af of het erg is dat berichten afgekapt kunnen worden.
De functie wordt inderdaad zo aangeroepen.
C:
1
vlc_message("Bericht hier!");


Wat betreft de applicatie kan het me gestolen worden wat er wordt ingelezen maar het inlezen moet wel gebeuren want het lijkt erop dat als ik dat niet doe het programma waar ik de berichten naar toe stuur (VLC) niet wil uitvoeren.

Wel bedankt voor die info over dat char strings in read only mem worden geplaatst. Een respons buffer zal er dus op een of andere manier wel moeten komen.

  • Odin
  • Registratie: November 2002
  • Laatst online: 30-07 10:54

Odin

¯¯¯¯¯

Topicstarter
Lomp maar het werkt, gewoon helemaal geen read uitvoeren. Op een of andere manier had ik begrepen dat wanneer ik VLC een command stuur de text die VLC terug stuurt moest afvangen. maar nu ik het hele read() stuk eruit heb gesloopt blijkt het ook prima te werken.

Toch enorm bedankt voor je hulp :)

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 30-11 00:17
Lijkt me niet een oplossing eigenlijk. Aan het feit of je / wat voor antwoord je krijgt lijkt me wat foutafhandeling vast the hangen.

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