c- valgrind(无效的free()/ delete / delete [] / realloc())Socketing

时间:2014-03-18 14:57:19

标签: c sockets valgrind

我正在编写一个简单的程序,使用套接字从服务器接收实际日期。 我收到这个错误,我不知道我在哪里犯了错误。

客户端:

/*  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);
}

服务器:

#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);
    }
}

我几乎可以肯定,使用包含实际日期的字符串来分配/释放空间有问题但是我看不到实际的错误。

编辑:

实际上,我不知道如何以这种方式解决这个问题,但我想出了其他的想法。 我只是在服务器上发送asctime(timeinfo)的结果而不使用char * s。 所以我不写日期给char * s。 程序现在工作正常,没有错误,但我想有办法以其他方式做到这一点。

嗯,尽管如此,非常感谢你的帮助,也很有帮助。

3 个答案:

答案 0 :(得分:2)

在您的服务器中,您在分配s后会覆盖asctime(...)。这会泄漏原始内存。此外,asctime的返回值是一个无法释放的静态缓冲区。

答案 1 :(得分:1)

以下是您的代码的摘录:

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);

请注意如果回答&#39;会发生什么?不等于1002 - 你在未初始化的值上调用free()。这可能是您所看到的错误的原因。 (这两个程序都存在同样的错误)

答案 2 :(得分:0)

参考服务器代码:

在此您将内存分配给s

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

在这里,您使用asctime()的值接收来覆盖指针,因此malloc()返回的原始值会丢失,从而导致内存泄漏:

    s=asctime(timeinfo);

然后,您尝试释放从asctime()收到的内容,这是对静态内存的引用,因此无法释放。

    free(s);