2016-12-12 8 views
-6

私は1つの関数のためにコードを書くのに大きな問題があります。 100-300のようなもっと小さなサイズはうまくいきますが、パケットからバッファをチェックするプロテクションがあるので、私のソースに問題があります。 ..hmm構造サイズが非常に大きく、最適化が必要

ここに問題があります - TPacket list [1000];

typedef struct testa 
{ 
    char t_A[10 + 1]; 
    char t_B[12 + 1]; 
    char t_C[32 + 1]; 
    char t_D[512 + 1]; 
    int  t_E; 
    char t_F[19 + 1]; 
    int  t_G; 
} TPacket; 

typedef struct testb 
{ 
    BYTE header; 
    TPacket list[1000]; // (If i put example 200 etc work) but when is so big = buffer mem_size overflow. memsize(131072) write_pos(32) iSize(598001) 
} Test; 

// FUNCTION TO SEND: 
    Test p; 
    p.header = HEADER_GC_T; 

    SQLMsg *pMsg = DBManager::instance().DirectQuery("SELECT * FROM table.list ORDER BY date DESC LIMIT 1000"); 
    MYSQL_ROW row; 
    int i = 0; 

    if(pMsg->uiSQLErrno != 0) 
     return; 

    while ((row = mysql_fetch_row(pMsg->Get()->pSQLResult))) 
    { 
     p.list[i] = TPacket(); 
     strncpy(p.list[i].t_A, row[1], sizeof(p.list[i].t_A)); 
     strncpy(p.list[i].t_B, row[2], sizeof(p.list[i].t_B)); 
     strncpy(p.list[i].t_C, row[3], sizeof(p.list[i].t_C)); 
     strncpy(p.list[i].t_D, row[4], sizeof(p.list[i].t_D)); 
     str_to_number(p.list[i].t_E, row[5]); 
     strncpy(p.list[i].t_F, row[6], sizeof(p.list[i].t_F) - 1); 
     str_to_number(p.list[i].t_G, row[7]); 
     i++; 
    } 

    if(pMsg->Get()->uiNumRows < 1000) 
    { 
     while (i < 1000) 
     { 
      p.list[i] = TPacket(); 
      strncpy(p.list[i].t_A, "", sizeof(p.list[i].t_A)); 
      strncpy(p.list[i].t_B, "", sizeof(p.list[i].t_B)); 
      strncpy(p.list[i].t_C, "", sizeof(p.list[i].t_C)); 
      strncpy(p.list[i].t_D, "", sizeof(p.list[i].t_D));   
      p.list[i].t_E = 0;   
      strncpy(p.list[i].t_F, "", sizeof(p.list[i].t_F) - 1);   
      p.list[i].t_G = 0;    
      i++; 
     } 
    } 
    ch->GetDesc()->Packet(&p, sizeof(p)); 
+2

実際の問題のように聞こえるのは、非ブロッキングセンドを使用する必要があるということです。 –

+1

CまたはC++を使用していますか? C++の場合は、cstringに 'std :: string'を、他の配列を置き換えるには' std :: vector'を提案します。 – NathanOliver

+2

それはあなたのスタックのために大きいです。 'TPacket list [1000];を' std :: vector list(1000);に置き換えてください。 –

答えて

0

あなたTest構造は、自動保存のためには大きすぎるかもしれません588000バイト、非常に大きいです。 staticで問題を解決する必要がありますが、コードは再入可能ではなく、スレッドセーフではありません。

問題が最大パケットサイズである場合は、送信をより小さいパケットに分割する必要があります。構造体とSQL SELECTステートメントの両方で、より少ない数の項目を使用します。

strncpy文字列が宛先配列よりも長い場合は、文字列を終了しません。この機能は決して使用しないでください。なぜあなたはstop using strncpy already!を読んでください。代わりに切り捨てを使用してコピーするが、送り先をNULLで終了する別の関数を使用できます。

TPacketのデフォルトのコンストラクタですべてのビット0に初期化されたTPacketが生成されると仮定すると、クリアループを大幅に簡素化できます。そうでない場合は、memsetを使用してください。

typedef struct testa { 
    char t_A[10 + 1]; 
    char t_B[12 + 1]; 
    char t_C[32 + 1]; 
    char t_D[512 + 1]; 
    int t_E; 
    char t_F[19 + 1]; 
    int t_G; 
} TPacket; 

typedef struct testb { 
    BYTE header; 
    TPacket list[200]; 
} Test; 

// Utility function: copy with truncation, return source string length 
// truncation occurred if return value >= size argument 
size_t bstrcpy(char *dest, size_t size, const char *src) { 
    size_t i; 
    /* copy the portion that fits */ 
    for (i = 0; i + 1 < size && src[i] != '\0'; i++) { 
     dest[i] = src[i]; 
    } 
    /* null terminate destination if possible */ 
    if (i < size) { 
     dest[i] = '\0'; 
    } 
    /* compute necessary length to allow truncation detection */ 
    while (src[i] != '\0') { 
     i++; 
    } 
    return i; 
} 

// FUNCTION TO SEND: 
void myfunction() { 
    Test p; 
    p.header = HEADER_GC_T; 

    SQLMsg *pMsg = DBManager::instance().DirectQuery("SELECT * FROM table.list ORDER BY date DESC LIMIT 200"); 
    MYSQL_ROW row; 
    int i = 0; 

    if (pMsg->uiSQLErrno != 0) 
     return; 

    while ((row = mysql_fetch_row(pMsg->Get()->pSQLResult))) { 
     p.list[i] = TPacket(); 
     bstrcpy(p.list[i].t_A, sizeof(p.list[i].t_A), row[1]); 
     bstrcpy(p.list[i].t_B, sizeof(p.list[i].t_B), row[2]); 
     bstrcpy(p.list[i].t_C, sizeof(p.list[i].t_C), row[3]); 
     bstrcpy(p.list[i].t_D, sizeof(p.list[i].t_D), row[4]); 
     str_to_number(p.list[i].t_E, row[5]); 
     bstrcpy(p.list[i].t_F, sizeof(p.list[i].t_F), row[6]); 
     str_to_number(p.list[i].t_G, row[7]); 
     i++; 
    } 

    if (i < 1000) { 
     memset(&p.list[i], 0, (1000 - i) * sizeof(p.list[i])); 
     //while (i < 1000) { 
     // p.list[i] = TPacket(); 
     // i++; 
     //} 
    } 
    ch->GetDesc()->Packet(&p, sizeof(p)); 
+0

@ Dr.Vendetta:なぜこの回答は受け入れられるとは思われませんか? – chqrlie

関連する問題