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



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

客户:

/*  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 odpowiedzn");
    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 = %sn", 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 waitingn");
        /*  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("%sn", asctime(timeinfo));
        s=asctime(timeinfo);
        printf("Size of s:%lxn", sizeof(s));
        length = htons(strlen(s));
        write (client_sockfd, &length, sizeof(length)); /* sending the answer string length to the client */

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

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

编辑:

实际上,我不知道如何以上述方式解决此问题,但我想出了其他想法。我只是在服务器上发送 asctime(timeinfo( 的结果,而不使用 char* s。所以我不会把日期写成字符*s。程序现在运行良好,没有错误,但我想有一种方法可以以其他方式做到这一点。

好吧,即使非常感谢您的帮助,还是有帮助的。

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

以下是代码的摘录:

char *s;
if(answer==1002){
   printf("Odebrano wlasciwa odpowiedzn");
   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 = %sn", s);
}
free(s);

请注意,如果 'answer' 不等于 1002 会发生什么——你正在对未初始化的值调用 free((。 这可能是您看到的错误的原因。 (两个程序中都存在相同的错误(

引用服务器代码:

在这里,您将内存分配给s

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

在这里,您用值 receive from asctime() 覆盖指针,因此 malloc() 返回的原始值将丢失,从而引入内存泄漏:

    s=asctime(timeinfo);

在这里,你尝试释放从asctime()接收到的东西,这是对静态内存的引用,并且不能释放。

    free(s);

最新更新