简体   繁体   中英

c- valgrind (Invalid free() / delete / delete[] / realloc()) Socketing

I am writing a simple program using sockets to receive actual date from server. I am getting this error and i don't know where i am making a mistake.

Client:

/*  Make the necessary includes and set up the variables.  */

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>

int main ()
{
    int sockfd;
    socklen_t len;
    struct sockaddr_in address;
    int result;
    int id=2, answer, length;
    char *s;

    /*  Create a socket for the client.  */

    sockfd = socket (AF_INET, SOCK_STREAM, 0);

    /* Name the socket, as agreed with the server.  */

    address.sin_family = AF_INET;
    address.sin_addr.s_addr = inet_addr ("127.0.0.1");
    address.sin_port = htons (9734);
    len = sizeof (address);

    /*  Now connect our socket to the server's socket.  */

    result = connect (sockfd, (struct sockaddr *) &address, len);

    if (result == -1)
    {
        perror ("oops: netclient");
        exit (1);
    }

    /*  We can now read/write via sockfd.  */
    write(sockfd, &id, sizeof(id)); /* sending the request id */

    read(sockfd, &answer, sizeof(answer));  /* receiving the answer id*/

    if(answer==1002){
    printf("Odebrano wlasciwa odpowiedz\n");
    read(sockfd, &length, sizeof(length)); /* receiving the answer string length*/

    s=(char*)malloc(length*sizeof(char));   /* receiving the string with the date */
    read(sockfd, s, length);    
    printf ("Date from server = %s\n", s);
    }
    free(s);
    close (sockfd);
    exit (0);
}

Server:

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <signal.h>
#include <unistd.h>
#include <time.h>
#include <string.h>

int main ()
{
    int server_sockfd, client_sockfd;
    int length;
    char *s;
    int id;
    int answer=1002;
    socklen_t server_len, client_len;
    time_t rtime;
    struct tm *timeinfo;
    struct sockaddr_in server_address;
    struct sockaddr_in client_address;

    server_sockfd = socket (AF_INET, SOCK_STREAM, 0);

    server_address.sin_family = AF_INET;
    server_address.sin_addr.s_addr = htonl (INADDR_ANY);
    server_address.sin_port = htons (9734);
    server_len = sizeof (server_address);
    bind (server_sockfd, (struct sockaddr *) &server_address, server_len);

    /*  Create a connection queue and wait for clients.  */

    listen (server_sockfd, 5);

    while (1)
    {


        printf ("server waiting\n");

        /*  Accept connection.  */

        client_len = sizeof (client_address);
        client_sockfd = accept (server_sockfd,
                (struct sockaddr *) &client_address,
                &client_len);

        /*  We can now read/write to the client on client_sockfd.
            The five second delay is just for this demonstration.  */
        read(client_sockfd, &id, sizeof(int)); /*receive request id */

        if(id==2){
        write(client_sockfd, &answer, sizeof(int)); /* sending an answer_id*/
        time(&rtime);
        timeinfo=localtime(&rtime);
        s=(char*)malloc(sizeof(asctime(timeinfo))*sizeof(char));
        printf("%s\n", asctime(timeinfo));
        s=asctime(timeinfo);
        printf("Size of s:%lx\n", sizeof(s));
        length = htons(strlen(s));

        write (client_sockfd, &length, sizeof(length)); /* sending the answer string length to the client */



        printf("Date: %s\n", s);
        write (client_sockfd, s, length);   /* sending string with date to the server */
        }

        free(s);
        close (client_sockfd);
    }
}

I am almost certain that there is something wrong with allocing/freeing the space with the string containing actual date but i can't see the actual mistake.

EDIT:

Actually, i didn't know how to solve this problem in this mentioned way but i've came up with other idea. I just send the result of asctime(timeinfo) over the server without using char* s. So i don't write the date to char *s. Program works fine now with no errors but i guess there is a way to do it some other way.

Well, even though, many thanks for the help, was helpful.

In your server, you overwrite s with asctime(...) after allocating it. This leaks the original memory. Also, the return value of asctime is a static buffer that cannot be freed.

Here's an excerpt from your code:

char *s;

if(answer==1002){
   printf("Odebrano wlasciwa odpowiedz\n");
   read(sockfd, &length, sizeof(length)); /* receiving the answer string length*/

   s=(char*)malloc(length*sizeof(char));   /* receiving the string with the date */
   printf ("Date from server = %s\n", s);
}
free(s);

Note what happens if 'answer' is not equal to 1002 -- you're calling free() on an uninitialized value. That is likely the cause of the error you are seeing. (This same mistake is present in both programs)

Refering the server code:

Here you allocate memory to s :

    s=(char*)malloc(sizeof(asctime(timeinfo))*sizeof(char));

Here you overwrite the pointer with the value receive from asctime() so the original value returned by malloc() is lost introducing a memory leak:

    s=asctime(timeinfo);

Here you then try to free what had been received from asctime() , which is a reference to static memory and gherefore cannot be freed.

    free(s);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM