Structure size so big, need optimization

Your Test structure is quite large, 588,000 bytes, which might be too large for automatic storage. Make it static should solve the problem, but will make your code non reentrant and definitely not thread safe.

If the problem is with the maximum packet size, you must break the transmission into smaller packets. Use a smaller number of items in both the structure and the SQL SELECT statement.

strncpy does not null terminate the strings if they are longer than the destination arrays. You should NEVER use this function. Read why you should stop using strncpy already!. You can instead use a different function that copies with truncation but does null terminate the destination.

The clearing loop can be drastically simplified, assuming the default constructor for TPacket produces a TPacket initialized to all bits 0. If it does not, just use memset to do that.

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));

Leave a Comment