在Ubuntu

时间:2018-01-21 11:53:51

标签: c sockets ubuntu memory-leaks

传递此函数后,我有内存泄漏。

void downloadFile(int sockfd) {


FILE *f;
   char *buff;
   int err, len = 0;
   char fitxer[STR_BASE];

   // Demanem a l'usuari el nom del fitxer a descarregar
   printf("Introdueix el nom del fitxer que vols descarregar (amb extensió incluida!): ");
   __fpurge(stdin);
   scanf("%[^\n]",fitxer);
   len = strlen(fitxer);

   // Si introdueix una cadena buida insistim...
   while(len<=0) {
      printf("Introdueix el nom del fitxer que vols descarregar (amb extensió incluida!): ");
      __fpurge(stdin);
      scanf("%[^\n]",fitxer);
      len = strlen(fitxer);
   }

   // Establim el final del string
   fitxer[strlen(fitxer)] = '\0';

   // Passem la llargada de la cadena a enviar
   write(sockfd, &len, sizeof(int));

   // Passem la cadena
   write(sockfd, &fitxer, len);

   // Guardem el fitxer
   read(sockfd, &err, sizeof(int));
   if (err==FILE_NOT_EXIST) {
      printf("***El fitxer indicat no existeix al directori!\n");
   } else {
      // Creem o concatenem un fitxer amb el nom del arxiu a descarregar
      f = fopen(fitxer,"a");
      len = 0;

      // Anem llegint bytes del servidor fins arribar al final del fitxer a descarregar
      read(sockfd, &len, sizeof(int));
      while (len > 0) {
         /* Natejem la cadena....
         for (int i = 0; i<MAX; i++) {
            buff[i] = '\0';
         }
         */
         buff = malloc((sizeof(char) * len) + 1);
         // Llegim els caracters a grabar
         read(sockfd, buff, len);
         //buff[strlen(buff)] = '\0';
         printf("BUFF = %s / LEN = %d\n",buff, len);

         // Grabem els caracters al fitxer
         fputs(buff, f);
         read(sockfd, &len, sizeof(int));
      }

      // Tanquem el fitxer
      fclose(f);
      printf("\n\n\n\n\n");
   }
}

正如您所看到的,它是从文件到服务器套接字到客户端的一步,在服务器中我看不到任何垃圾,但是在执行该函数后在客户端中,如果我再次执行它会返回奇怪的字符:

BUFF = #include <w�1 / LEN = 10
BUFF = sys/types.w�1 / LEN = 10
BUFF = h>
#incluw�1 / LEN = 10
BUFF = de <sys/sow�1 / LEN = 10
BUFF = cket.h>
#w�1 / LEN = 10
BUFF = include <sw�1 / LEN = 10
BUFF = tdio.h>
#w�1 / LEN = 10
BUFF = include <sw�1 / LEN = 10
BUFF = tring.h>
w�1 / LEN = 10
BUFF = #include <w�1 / LEN = 10
BUFF = netinet/inw�1 / LEN = 10
BUFF = .h>
#inclw�1 / LEN = 10
BUFF = ude <arpa/w�1 / LEN = 10
BUFF = inet.h>
#w�1 / LEN = 10
BUFF = include <uw�1 / LEN = 10
BUFF = nistd.h>
w�1 / LEN = 10
BUFF = #include <w�1 / LEN = 10
w�1 / LEN = 10>
BUFF = 
{w�1 / LEN = 1

2 个答案:

答案 0 :(得分:1)

您必须致电free(buff);,否则您有泄密。

答案 1 :(得分:1)

您的代码中存在大量错误。我们来看几个:

   char fitxer[STR_BASE];

   printf("Introdueix el nom del fitxer que vols descarregar (amb extensió incluida!): ");
   __fpurge(stdin);
   scanf("%[^\n]",fitxer);
   len = strlen(fitxer);

为什么len会有任何有意义的价值?请注意,fitxer未初始化,因此如果scanf失败则会包含垃圾,因此strlen可能会在输入null之前找到数字字符。您应该检查scanf

的返回值
  // Establim el final del string
  fitxer[strlen(fitxer)] = '\0';

有趣....你想要终止字符串,并为此寻找终止空字符。请注意,strlen将遍历第一个字符中的字符串,直到遇到空字符。 (因此,如果strlen找到一个空字符,则该字符串已经终止,如果该字符串未终止,则strlen是查找其长度的错误方法。)

   read(sockfd, &err, sizeof(int));
   if (err==FILE_NOT_EXIST) {

在这里,您将整数读入err,然后想知道您所读取的值是否等于FILE_NOT_EXIST?我不明白那个逻辑。那是你服务器的回复吗?服务器和客户端上的int的字节数是否相同,称为 endianness ?但是如果你想知道read是否成功,你必须检查它是否返回你期望的字节数,如果没有,请检查errno是否有原因。你应该检查一下所有内容。

     read(sockfd, buff, len);
     //buff[strlen(buff)] = '\0';

您也必须检查read的返回值。你注释掉的那一行很重要,但不正确,假设你收到的确实是一个字符串而不是二进制数据。它应该是:

     if (read(sockfd, buff, len)!=len) ...// error
     buff[len] = '\0';

正如其他人所说,你必须在不再需要时释放你从malloc获得的记忆:

    free(buff);