Avatar billede inglenook Praktikant
04. marts 2004 - 23:10 Der er 12 kommentarer og
1 løsning

Memory leak !

Jeg har foelgende kode (se herunder). Mit problem er at mit program 'aeder' ca. et par MB i timen (koerer i uendelig loop)

Er der nogen der kan se hvor det gaar galt......?

#include <stdlib.h>
#include <stdio.h>
#include <libpq-fe.h>
#include <string.h>
#include <time.h>

#include <sys/socket.h>
#include <fcntl.h>
#include <netdb.h>
#include <errno.h>
#include <unistd.h>


void smssend(char *hostname,char *til,char *smsstart,char *smstext)
{
  int sd,status,tmp,len,ix,noblock,postlen;

  char *buf,ownhost[100],resp[512];
  struct sockaddr local,remote;
  struct hostent *hostinfo;
  time_t t;

  noblock=1;
  //  hostname = "localhost";

  sd=socket(AF_INET,SOCK_STREAM,0);
  if(sd<0) {
      printf("Error creating socket: %s\n",strerror(errno));
      goto slut;
  }

  local.sa_family=AF_INET;
  memset(local.sa_data,0,sizeof(local.sa_data));
  status=bind(sd,&local,sizeof(local));
  if(status<0) {
      printf("Error binding socket: %s\n",strerror(errno));
      goto slut;
  }

  hostinfo=gethostbyname(hostname);

  if(!hostinfo) {
      printf("Error looking up host: %s\n",hostname);
      goto slut;
  }

  remote.sa_family=hostinfo->h_addrtype;
  memcpy(remote.sa_data+2,hostinfo->h_addr_list[0],hostinfo->h_length);
  *((short *)remote.sa_data)=80;
  tmp=remote.sa_data[0];
  remote.sa_data[0]=remote.sa_data[1];
  remote.sa_data[1]=tmp;
  status=connect(sd,&remote,sizeof(remote));

  if(status!=0) {
      printf("Error connecting to host: %s port: %d\n",hostname,80);
      goto slut;
  }
printf("Sending something to:%s\n",til);
      postlen=70 + strlen(til) + strlen(smsstart) + strlen(smstext);

  gethostname(ownhost,sizeof(ownhost));
    buf = (char*)malloc(2000+strlen(smstext));
  sprintf(buf,"POST /http/sendmsg HTTP/1.0\r\n"
              "Host: something.somewhere.Com\r\n"
              "Content-Type: application/x-www-form-urlencoded\r\n"
              "Content-length: %d\r\n\r\n"
              "api_id=xxxxx&user=username&password=hemmeligt&to=%s"
          "&from=myDomain&text=%s%s\r\n\r\n",postlen,til,smsstart,smstext);
          status=send(sd,buf,strlen(buf),0);

  /* read response

  ix=0;
  while ((len=recv(sd,resp+ix,sizeof(resp)-ix-1,0))>0) {
      ix = ix + len;
  }
  resp[ix]='\0';
  printf("%s\n",resp);

              */
slut:
free(buf);
  close(sd);
  return;
}

void mailsend(char *hostname,char *to,char *dest,char *body)
{
  int sd,status,tmp,len,ix,noblock;

  char *buf,ownhost[100],resp[512];
  struct sockaddr local,remote;
  struct hostent *hostinfo;
  time_t t;

  noblock=1;
  //  hostname = "localhost";

  sd=socket(AF_INET,SOCK_STREAM,0);
  if(sd<0) {
      printf("Error creating socket: %s\n",strerror(errno));
      goto fin;
  }

  local.sa_family=AF_INET;
  memset(local.sa_data,0,sizeof(local.sa_data));
  status=bind(sd,&local,sizeof(local));
  if(status<0) {
      printf("Error binding socket: %s\n",strerror(errno));
      goto fin;
  }

  hostinfo=gethostbyname(hostname);

  if(!hostinfo) {
      printf("Error looking up host: %s\n",hostname);
      goto fin;
  }

  remote.sa_family=hostinfo->h_addrtype;
  memcpy(remote.sa_data+2,hostinfo->h_addr_list[0],hostinfo->h_length);
  *((short *)remote.sa_data)=25;
  tmp=remote.sa_data[0];
  remote.sa_data[0]=remote.sa_data[1];
  remote.sa_data[1]=tmp;
  status=connect(sd,&remote,sizeof(remote));

  if(status!=0) {
      printf("Error connecting to host: %s port: %d\n",hostname,25);
      goto fin;
  }
printf("Sending mail to:%s\n",to);

  gethostname(ownhost,sizeof(ownhost));
    buf = (char*)malloc(2000+strlen(body));
  sprintf(buf,"HELO memoryspin\r\n"
              "MAIL FROM: <myaddress@myDomain.uk>\r\n"
              "RCPT TO: <%s>\r\n"
              "DATA\r\n"
              "From: Me <myaddress@myDomain.uk>\r\n"
              "To: %s <%s>\r\n"
              "Subject: Mail 2 u\r\n"
              "MIME-version: 1.0\r\n"
              "Content-type: text/html; Charset=iso-8859-1\r\n"
              "\r\n"
              "<html><title><Mail 2 u</title><body "
              "bgcolor=\"bebebe\"><table align=\"center\" border=\"4\">"
              "<tr><td align=\"center\">"
              "%s"
              "</td></tr><tr><td align=\"center\"> This is a mail from "
              "<a href=\"www.myDomain.com\">myDomain.Com </a></td>"
              "</tr></table></body></html>"
              "\r\n.\r\n"
              "QUIT\r\n",to,dest,to,body);
          status=send(sd,buf,strlen(buf),0);

free(buf);
fin:
  close(sd);
  return;
}

int main()
{

  PGconn *conn;
  PGresult *result;
  int i;
  int j;
  time_t rawtime;

  const char *connection_str = "host=localhost dbname=xx01";

  j = 1;

    while(j < 4)
{

  conn = PQconnectdb(connection_str);
  if (PQstatus(conn) == CONNECTION_BAD) {
      fprintf(stderr, "Connection to %s failed, %s", connection_str,
      PQerrorMessage(conn));
  } else {
       
        time ( &rawtime );

        printf("\n%s",ctime(&rawtime));
      printf("Connected !\n");
     
  }

  result = PQexec(conn, "update tbl01 set now = now()");

  if (!result) {
      printf("PQexec command failed, no error code\n");
  } else {
      switch (PQresultStatus(result)) {
      case PGRES_COMMAND_OK:
        printf("Updated tbl11 (now).\n");
        break;
      case PGRES_TUPLES_OK:
        printf("Updated tbl01 (now).\n");

        break;
        default:
      printf("Command failed with code %s, error message %s\n",
        PQresStatus(PQresultStatus(result)),
        PQresultErrorMessage(result));
      break;
      }
  PQclear(result);
  }


  result = PQexec(conn, "insert into tblmain1 select a.id,a.text, \
                          b.email,b.fname||' '||b.lname from tbl01 a, \
                          tbluser b, \
                          tbl11 c where a.time between \
                          (to_timestamp(c.last,'yyyy-mm-dd hh24:mi:ss') + \
                          interval '1 minute') \
                          and (to_timestamp(c.now,'yyyy-mm-dd hh24:mi:ss') + \
                          interval '1 minute') and (b.id = a.id)");

  if (!result) {
      printf("PQexec command failed, no error code\n");
  } else {
      switch (PQresultStatus(result)) {
      case PGRES_COMMAND_OK:
        printf("tbl01: Query found: %s rows.\n",PQcmdTuples(result));
        break;
      case PGRES_TUPLES_OK:
        printf("tbl01: Query found: %s rows.\n",PQntuples(result));
   

        break;
        default:
      printf("Command failed with code %s, error message %s\n",
        PQresStatus(PQresultStatus(result)),
        PQresultErrorMessage(result));
      break;
      }
  PQclear(result);
  }

  result = PQexec(conn, "insert into tbl10 select a.id,a.text, \
                          b.smsnumber from tbl08 a,tblnumbers b, \
                          tbl11 c where a.time between \
                          (to_timestamp(c.last,'yyyy-mm-dd hh24:mi:ss') + \
                          interval '1 minute') \
                          and (to_timestamp(c.now,'yyyy-mm-dd hh24:mi:ss') + \
                          interval '1 minute') and (b.id = a.id)");

  if (!result) {
      printf("PQexec command failed, no error code\n");
  } else {
      switch (PQresultStatus(result)) {
      case PGRES_COMMAND_OK:
        printf("tbl08: Query found: %s rows.\n",PQcmdTuples(result));
        break;
      case PGRES_TUPLES_OK:
        printf("tbl08: Query found: %s rows.\n",PQntuples(result));
   

        break;
        default:
      printf("Command failed with code %s, error message %s\n",
        PQresStatus(PQresultStatus(result)),
        PQresultErrorMessage(result));
      break;
      }
  PQclear(result);
  }

    result = PQexec(conn, "insert into tbl09 select a.id,a.text,b.email, \
                          b.fname||' '||b.lname from tbl03 a,tbluser b, \
                          tbl11 c where \
                          to_char(a.time,'hh24:mi:ss') between \
                          to_char(c.last + \
                          interval '1 minute','hh24:mi:ss') \
                          and to_char(c.now + \
                        interval '1 minute','hh24:mi:ss') and (b.id = a.id)");

  if (!result) {
      printf("PQexec command failed, no error code\n");
  } else {
      switch (PQresultStatus(result)) {
      case PGRES_COMMAND_OK:
        printf("tbl03: Query found: %s rows.\n",PQcmdTuples(result));
        break;
      case PGRES_TUPLES_OK:
        printf("tbl03: Query found: %s rows.\n",PQntuples(result));
   

        break;
        default:
      printf("Command failed with code %s, error message %s\n",
        PQresStatus(PQresultStatus(result)),
        PQresultErrorMessage(result));
      break;
      }
  PQclear(result);
  }

  result = PQexec(conn, "insert into tbl09 select a.id,a.text,b.email, \
                          b.fname||' ' ||b.lname from tbl04 a,tbluser b, \
                          tbl11 c where \
                      a.weekday = to_char(now(),'Day') and  \
                          to_char(a.time,'hh24:mi:ss') between \
                          to_char(c.last + interval '1 minute','hh24:mi:ss') \
                          and \
                          to_char(c.now + interval '1 minute','hh24:mi:ss') \
                          and b.id = a.id");

  if (!result) {
      printf("PQexec command failed, no error code\n");
  } else {
      switch (PQresultStatus(result)) {
      case PGRES_COMMAND_OK:
        printf("tbl04: Query found: %s rows.\n",PQcmdTuples(result));
        break;
      case PGRES_TUPLES_OK:
        printf("tbl04: Query found: %s rows.\n",PQntuples(result));
   

        break;
        default:
      printf("Command failed with code %s, error message %s\n",
        PQresStatus(PQresultStatus(result)),
        PQresultErrorMessage(result));
      break;
      }
  PQclear(result);
  }

  result = PQexec(conn, "insert into tbl09 select a.id,a.text,b.email, \
                          b.fname||' '||b.lname from tbl06 a,tbluser b, \
                          tbl11 c where \
                          trim(to_char(a.day,'00')) =  \
                          trim(to_char(now(),'DD')) and \
                          to_char(a.time,'hh24:mi:ss') between \
                      to_char(c.last + interval '1 minute','hh24:mi:ss') \
                          and \
                      to_char(c.now + interval '1 minute','hh24:mi:ss') \
                          and b.id = a.id");

  if (!result) {
      printf("PQexec command failed, no error code\n");
  } else {
      switch (PQresultStatus(result)) {
      case PGRES_COMMAND_OK:
        printf("tbl06: Query found: %s rows.\n",PQcmdTuples(result));
        break;
      case PGRES_TUPLES_OK:
        printf("tbl06: Query found: %s rows.\n",PQntuples(result));
   

        break;
        default:
      printf("Command failed with code %s, error message %s\n",
        PQresStatus(PQresultStatus(result)),
        PQresultErrorMessage(result));
      break;
      }
  PQclear(result);
  }

  result = PQexec(conn, "insert into tbl09 select a.id,a.text,b.email, \
                b.fname||' '||b.lname from tbl07 a,tbluser b, \
                tbl11 c where a.time \
                between (to_timestamp(c.last,'yyyy-mm-dd hh24:mi:ss') + \
                interval '1 minute') \
                and (to_timestamp(c.now,'yyyy-mm-dd hh24:mi:ss') + \
                interval '1 minute') and (b.id = a.id)");

  if (!result) {
      printf("PQexec command failed, no error code\n");
  } else {
      switch (PQresultStatus(result)) {
      case PGRES_COMMAND_OK:
        printf("tbl07: Query found: %s rows.\n",PQcmdTuples(result));
        break;
      case PGRES_TUPLES_OK:
        printf("tbl07: Query found: %s rows.\n",PQntuples(result));
   

        break;
        default:
      printf("Command failed with code %s, error message %s\n",
        PQresStatus(PQresultStatus(result)),
        PQresultErrorMessage(result));
      break;
      }
  PQclear(result);
  }

  result = PQexec(conn, "update tbl11 set last = \
                          (select (now + interval '1 second') \
                          from tbl11)");

  if (!result) {
      printf("PQexec command failed, no error code\n");
  } else {
      switch (PQresultStatus(result)) {
      case PGRES_COMMAND_OK:
        printf("Updated tbl11 (last).\n");
        break;
      case PGRES_TUPLES_OK:
        printf("Updated tbl11 (last).\n");
   

        break;
        default:
      printf("Command failed with code %s, error message %s\n",
        PQresStatus(PQresultStatus(result)),
        PQresultErrorMessage(result));
      break;
      }
  PQclear(result);
  }

  result = PQexec(conn, "select email,name,text from tbl09");

  if (!result) {
      printf("PQexec command failed, no error code\n");
  } else {
      switch (PQresultStatus(result)) {
      case PGRES_COMMAND_OK:
        printf("Command executed OK, %s rows
              affected\n",PQcmdTuples(result));
        break;
      case PGRES_TUPLES_OK:
    //      printf("Query have returned data:\n");
   
    for (i = 0; i < PQntuples(result); i++)
      mailsend("localhost",PQgetvalue(result,i,0), \
                                        PQgetvalue(result,i,1), \
                                        PQgetvalue(result,i,2));

        break;
        default:
      printf("Command failed with code %s, error message %s\n",
        PQresStatus(PQresultStatus(result)),
        PQresultErrorMessage(result));
      break;
      }
  PQclear(result);
  }
  result = PQexec(conn, "truncate table tbl09");

  if (!result) {
      printf("PQexec command failed, no error code\n");
  } else {
      switch (PQresultStatus(result)) {
      case PGRES_COMMAND_OK:
        printf("Truncated table tbl09 !\n",PQcmdTuples(result));
        break;
      case PGRES_TUPLES_OK:
        printf("Truncated table tbl09 !\n",PQntuples(result));
   

        break;
        default:
      printf("Command failed with code %s, error message %s\n",
        PQresStatus(PQresultStatus(result)),
        PQresultErrorMessage(result));
      break;
      }


  PQclear(result);
  }

  result = PQexec(conn, "select smsnumber,text from tbl10");

  if (!result) {
      printf("PQexec command failed, no error code\n");
  } else {
      switch (PQresultStatus(result)) {
      case PGRES_COMMAND_OK:
        printf("Command executed OK, %s rows
              affected\n",PQcmdTuples(result));
        break;
      case PGRES_TUPLES_OK:
    //      printf("Query have returned data:\n");
   
    for (i = 0; i < PQntuples(result); i++)
      smssend("api.clickatell.com",PQgetvalue(result,i,0), \
              "MemorySpin.Com ",PQgetvalue(result,i,1));

        break;
        default:
      printf("Command failed with code %s, error message %s\n",
        PQresStatus(PQresultStatus(result)),
        PQresultErrorMessage(result));
      break;
      }
  PQclear(result);
  }
  result = PQexec(conn, "truncate table tbl10");

  if (!result) {
      printf("PQexec command failed, no error code\n");
  } else {
      switch (PQresultStatus(result)) {
      case PGRES_COMMAND_OK:
        printf("Truncated table tbl10 !\n",PQcmdTuples(result));
        break;
      case PGRES_TUPLES_OK:
        printf("Truncated table tbl10 !\n",PQntuples(result));
   

        break;
        default:
      printf("Command failed with code %s, error message %s\n",
        PQresStatus(PQresultStatus(result)),
        PQresultErrorMessage(result));
      break;
      }


  PQclear(result);
  }



  PQfinish(conn);

  printf("Done !\n");

  sleep(58);
    }

  return EXIT_SUCCESS;
}
Avatar billede arne_v Ekspert
04. marts 2004 - 23:17 #1
Får:

PQfinish(conn);

lukket efter:

conn = PQconnectdb(connection_str);
 
?
Avatar billede inglenook Praktikant
04. marts 2004 - 23:23 #2
Hej Arne. Ja, der der er kun een 'conn = PQconnectdb(connection_str)' og een 'PQfinish(conn)' Der bliver aabnet og lukket (ca.) hvert minut, men jeg tror ikke det er der problemet er......
Avatar billede inglenook Praktikant
04. marts 2004 - 23:27 #3
Har kigget lidt paa mine buffere men kan ikke finde et problem der. Btw., koden koerer paa en Linux box (RH9) med en PostgreSQL database.
Avatar billede arne_v Ekspert
04. marts 2004 - 23:30 #4
Det ser ud som at i smssend kan:

free(buf);
 
blive kaldt uden at buf er blevet malloc'et
Avatar billede inglenook Praktikant
04. marts 2004 - 23:34 #5
ok, burde ha' sagt det foer, men jeg har proevet at koere det med tom database, mao. sendmail og sendsms bliver ikke kaldt overhovedet......
Avatar billede inglenook Praktikant
04. marts 2004 - 23:35 #6
Det er mao. i Main problemet ligger. Maaske et problem med PostgreSQL's include fil ?
Avatar billede inglenook Praktikant
04. marts 2004 - 23:38 #7
P.S. Hvordan mener du buf can blive freed uden allocation ....? Det forstaar jeg ikke helt (OK, som du ved er jeg helt ny i C++)....
Avatar billede jpk Nybegynder
05. marts 2004 - 08:40 #8
Er memory increase proportionalt med antallet af gennemløb?
Altså, hvis du sætter sleep time ned, stiger memory-forbruget så tilsvarende?

Kan du kommentere dele ud, der får problemet til at forsvinde?
Avatar billede arne_v Ekspert
05. marts 2004 - 08:41 #9
if(status!=0) {
      ...
      goto slut;
}
...
buf = (char*)malloc(2000+strlen(smstext));
...
slut:
free(buf);
 
hvis if er opfyldt så ...
Avatar billede segmose Nybegynder
05. marts 2004 - 08:42 #10
Metode: del og hersk. (kopier hele projectet til et nyt sted)
udkommenter al uvæsentlig kode, så du er sikker på at fejlen ikke ligger der.
udkomenter alt mellem din
conn = PQconnectdb(connection_str);
og
PQfinish(conn);
så vi er sikker på at fejlen ligger imellem.
Tag derefter at udkommenter den sidste halvdel af koden i hoved løkken, du ved så i hvilken halvdel fejlen ligger, fortsæt med enten at inkludere eller ekskludere halv delen af den del der giver fejlen.
Avatar billede inglenook Praktikant
05. marts 2004 - 11:48 #11
Tak til begge. Jeg vil proeve forslagene i loebet af naeste uge. Arne, laegger du ogsaa lige et svar.....
Avatar billede inglenook Praktikant
05. marts 2004 - 11:49 #12
ups, jpk, laegger du ogsaa lige et svar...
Avatar billede inglenook Praktikant
05. marts 2004 - 15:28 #13
Har re-booted maskinen og ladet den staa i ca. 4 timer uden at koere nogen applikationer (ud over 3 VNC sessions der kun lyttede). Hukommelses forbruget er lige saa stoet steget fra 160Mb til 400Mb saa jeg tror jeg skal have kigget paa mine services foerst......
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester