-1

この長いコードは、ソケットを使用してPOSTリクエストを送信しています。コード全体は文句なしに機能しますが、私が今直面しているのは、CPUパワーを大量に消費し、メモリ(RAM)を大量に使用していることです。

私のラップトップは非常に速く熱くなっているので、そして私のMacを見てみると、それを見ることができます。

私はバグや、その非常に大きなメモリの問題がどこにあるかを見つけようとしましたが、見つかりませんでした。私は自分でそれを修正しようとして1か月以上を費やしましたが、正直に言うと私が何をしているのかわかりません。

私はとても必死だったので、あらゆる種類の解放方法を入れました..それが間違っていたとしても..それが変化したかどうかを確認するだけでしたが、何もしませんでした..

だから今、私は何が間違っているのか、これを修正する方法がわかりません、助けてください…</ p>

select、momentでコードを更新します...最初にコードをクリーンアップしようとします

4

2 に答える 2

4

まず、malloc()とdelete[]を混在させないでください。それらは同じメモリアロケータを参照する場合としない場合があります。したがって、malloc()/ free()またはnew char [] /delete[]のペアを使用してください。

問題はここにあります(Database()関数内):ひどいメモリリークがあります。結果の受け渡しにこのようなメモリを割り当てないでください。バッファをよりよく使用します。プログラムはマルチスレッドであるため、スタック上のバ​​ッファーを使用してください。割り当てられていないものに対してdelete[]を呼び出さないでください(「charBuf [100];」のようなvar宣言は割り当てではありません)。

新しいバージョン(main()関数とstrip()関数を省略しました。インクルードも含まれています):

#define MAX_ECHO_SIZE (1024)
#define MAX_RESPONSE_SIZE (1024)

void process_http(int sockfd, const char *host, const char *page, const char *poststr, char* OutResponse)
 {
    char* ptr;
    char sendline[MAXLINE + 1], recvline[MAXLINE + 1];
    ssize_t n;

    snprintf(sendline, MAXSUB, 
         "POST %s HTTP/1.0\r\n"  // POST or GET, both tested and works. Both HTTP 1.0 HTTP 1.1 works, but sometimes 
         "Host: %s\r\n"     //oth HTTP 1.0 HTTP 1.1 works, but sometimes HTTP 1.0 works better in localhost type
         "Content-type: application/x-www-form-urlencoded\r\n"
         "Content-length: %d\r\n\r\n"
         "%s\r\n", page, host, (unsigned int)strlen(poststr), poststr);

    if (write(sockfd, sendline, strlen(sendline))>= 0) 
    {
        while ((n = read(sockfd, recvline, MAXLINE)) > 0) 
        {
            recvline[n] = '\0';

            if(fputs(recvline,stdout) ==EOF) { cout << ("fputs erros"); }
            ptr = strstr(recvline, "\r\n\r\n");
            strip(ptr, "\r\n\r\n");

            // check len for OutResponse here ?
            snprintf(OutResponse, 6000,"%s", ptr);
        }
    }
}

int Database( const char * hname,  const char * page,  const char * var, const char * poststr,  int  port, char* EchoResponse, int MaxEchoLen){

    char url[MAXLINE];
    char response[MAX_RESPONSE_SIZE];

    snprintf(url, MAXLINE, "%s=%s", var, poststr);

    short int sockfd ;
    struct sockaddr_in servaddr;
    struct hostent *hptr;
    char str[MAXLINE];
    char** pptr;

    hptr = gethostbyname(hname);

    sockfd = socket(AF_INET, SOCK_STREAM, 0);

    if (!hptr) {
        cout << ("host not found\n");
        return -1; // "host not found";
    }

    if (hptr->h_addrtype == AF_INET && (pptr = hptr->h_addr_list) != NULL) {
        inet_ntop(hptr->h_addrtype, *pptr, str, sizeof(str)); 
    }
    if (sockfd  >= 0  ) {
        bzero(&servaddr, sizeof(servaddr));
        servaddr.sin_family = AF_INET;
        servaddr.sin_port = htons(port);
        inet_pton(AF_INET, str, &servaddr.sin_addr);

        if (connect(sockfd, (SA *) & servaddr, sizeof(servaddr)) < 0) {
            return -2; // "Server down, connect error";
        }
        else {
            process_http(sockfd, hname, page, url, &response[0], MAX_RESPONSE_SIZE);

            int len = strlen(response)+1;
            if(len >= MaxEchoLen) { return -3; /* buffer too small*/ }

            // Copy the contents with
            strcpy(EchoResponse, response);

            /// You must not free all of char[] allocated on stack
            close(sockfd);

            return 0; // OK
        }
    }
}

void *multithreading1( void *ptr ) {
    char LocalEchoResponse[MAX_ECHO_SIZE];

    while (1) {
            int RetCode = Database("2.107.xx.xxx", "/ajax.php", "submit", "HEllo WORLD", 80, &LocalEchoResponse[0], MAX_ECHO_SIZE);
            /// check the error
    }   
}
于 2012-05-30T10:39:27.513 に答える
1

strip_copyでかなり大きなメモリリークが発生しています。返品後に何を入れても、実行されることはありません。コンパイラがこれについて文句を言わなかったことに驚いた。process_http()関数でも同じ問題が発生します。

次のように修正します。

static void strip_copy(char const *s, char *buf, const char * SPACE)
{
    if (buf)
    {
        char *p = buf;
        char const *q;
        int n;
        for (q = s; *q; q += n + strspn(q+n, SPACE))
        {
            n = strcspn(q, SPACE);
            strncpy(p, q, n);
            p += n;
        }
        *p++ = '\0';
        buf = (char*)realloc(buf, p - buf);
    }
}

// Then call it like this
char *buf = new[1 + strlen(s)];
strip_copy(s, buf, ' ');
// use buf
delete [] buf;

そしてprocess_http()で

const char*  process_http(int sockfd, const char *host, const char *page, const char *poststr)
{
    ....
    // delete here only what you dynamically 
    // allocated with new() BEFORE the return
    return response; // n
}

そして、malloc()とdelete()を混ぜないでください:

  • malloc()はfree()と一緒に行きます
  • new()はdelete()と一緒になります

これは使用されるメモリとは関係ありませんが、read()/ write()を直接呼び出す代わりに、select()を使用して、いつ読み取りまたは書き込みの準備ができているかを知る必要があります。関連する質問は次のとおりです:https ://stackoverflow.com/a/10800029/1158895

于 2012-05-30T10:37:08.793 に答える