Merge pull request #7344 from taosdata/fix/TD-5890
fixed realloc can cause memory leak
This commit is contained in:
commit
19aaf70363
|
@ -98,6 +98,7 @@ int ConvertString(char *buf, size_t nBytes, UINT cpFrom, UINT cpTo, LPCSTR lpDef
|
||||||
char *DupAndConvert(const char *string, UINT cpFrom, UINT cpTo, LPCSTR lpDefaultChar) {
|
char *DupAndConvert(const char *string, UINT cpFrom, UINT cpTo, LPCSTR lpDefaultChar) {
|
||||||
int nBytes;
|
int nBytes;
|
||||||
char *pBuf;
|
char *pBuf;
|
||||||
|
char *pBuf1;
|
||||||
nBytes = 4 * ((int)lstrlen(string) + 1); /* Worst case for the size needed */
|
nBytes = 4 * ((int)lstrlen(string) + 1); /* Worst case for the size needed */
|
||||||
pBuf = (char *)malloc(nBytes);
|
pBuf = (char *)malloc(nBytes);
|
||||||
if (!pBuf) {
|
if (!pBuf) {
|
||||||
|
@ -110,8 +111,9 @@ char *DupAndConvert(const char *string, UINT cpFrom, UINT cpTo, LPCSTR lpDefault
|
||||||
free(pBuf);
|
free(pBuf);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
pBuf = realloc(pBuf, nBytes+1);
|
pBuf1 = realloc(pBuf, nBytes+1);
|
||||||
return pBuf;
|
if(pBuf1 == NULL && pBuf != NULL) free(pBuf);
|
||||||
|
return pBuf1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CountCharacters(const char *string, UINT cp) {
|
int CountCharacters(const char *string, UINT cp) {
|
||||||
|
|
|
@ -68,6 +68,7 @@ int BreakArgLine(LPSTR pszCmdLine, char ***pppszArg) {
|
||||||
int iString = FALSE; /* TRUE = string mode; FALSE = non-string mode */
|
int iString = FALSE; /* TRUE = string mode; FALSE = non-string mode */
|
||||||
int nBackslash = 0;
|
int nBackslash = 0;
|
||||||
char **ppszArg;
|
char **ppszArg;
|
||||||
|
char **ppszArg1;
|
||||||
int iArg = FALSE; /* TRUE = inside an argument; FALSE = between arguments */
|
int iArg = FALSE; /* TRUE = inside an argument; FALSE = between arguments */
|
||||||
|
|
||||||
ppszArg = (char **)malloc((argc+1)*sizeof(char *));
|
ppszArg = (char **)malloc((argc+1)*sizeof(char *));
|
||||||
|
@ -89,7 +90,10 @@ int BreakArgLine(LPSTR pszCmdLine, char ***pppszArg) {
|
||||||
if ((!iArg) && (c != ' ') && (c != '\t')) { /* Beginning of a new argument */
|
if ((!iArg) && (c != ' ') && (c != '\t')) { /* Beginning of a new argument */
|
||||||
iArg = TRUE;
|
iArg = TRUE;
|
||||||
ppszArg[argc++] = pszCopy+j;
|
ppszArg[argc++] = pszCopy+j;
|
||||||
ppszArg = (char **)realloc(ppszArg, (argc+1)*sizeof(char *));
|
ppszArg1 = (char **)realloc(ppszArg, (argc+1)*sizeof(char *));
|
||||||
|
if(ppszArg1 == NULL && ppszArg != NULL)
|
||||||
|
free(ppszArg);
|
||||||
|
ppszArg = ppszArg1;
|
||||||
if (!ppszArg) return -1;
|
if (!ppszArg) return -1;
|
||||||
pszCopy[j] = c0 = '\0';
|
pszCopy[j] = c0 = '\0';
|
||||||
}
|
}
|
||||||
|
@ -212,7 +216,7 @@ int _initU(void) {
|
||||||
fprintf(stderr, "Warning: Can't convert the argument line to UTF-8\n");
|
fprintf(stderr, "Warning: Can't convert the argument line to UTF-8\n");
|
||||||
_acmdln[0] = '\0';
|
_acmdln[0] = '\0';
|
||||||
}
|
}
|
||||||
realloc(_acmdln, n+1); /* Resize the memory block to fit the UTF-8 line */
|
//realloc(_acmdln, n+1); /* Resize the memory block to fit the UTF-8 line */
|
||||||
/* Should not fail since we make it smaller */
|
/* Should not fail since we make it smaller */
|
||||||
|
|
||||||
/* Record the console code page, to allow converting the output accordingly */
|
/* Record the console code page, to allow converting the output accordingly */
|
||||||
|
|
|
@ -196,6 +196,7 @@ not_compact_enough:
|
||||||
/* Normally defined in stdlib.h. Output buf must contain PATH_MAX bytes */
|
/* Normally defined in stdlib.h. Output buf must contain PATH_MAX bytes */
|
||||||
char *realpath(const char *path, char *outbuf) {
|
char *realpath(const char *path, char *outbuf) {
|
||||||
char *pOutbuf = outbuf;
|
char *pOutbuf = outbuf;
|
||||||
|
char *pOutbuf1;
|
||||||
int iErr;
|
int iErr;
|
||||||
const char *pc;
|
const char *pc;
|
||||||
|
|
||||||
|
@ -242,8 +243,11 @@ realpath_failed:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!outbuf) pOutbuf = realloc(pOutbuf, strlen(pOutbuf) + 1);
|
if (!outbuf) {
|
||||||
return pOutbuf;
|
pOutbuf1 = realloc(pOutbuf, strlen(pOutbuf) + 1);
|
||||||
|
if(pOutbuf1 == NULL && pOutbuf) free(pOutbuf);
|
||||||
|
}
|
||||||
|
return pOutbuf1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -517,6 +521,7 @@ int ResolveLinksA(const char *path, char *buf, size_t bufsize) {
|
||||||
/* Normally defined in stdlib.h. Output buf must contain PATH_MAX bytes */
|
/* Normally defined in stdlib.h. Output buf must contain PATH_MAX bytes */
|
||||||
char *realpathU(const char *path, char *outbuf) {
|
char *realpathU(const char *path, char *outbuf) {
|
||||||
char *pOutbuf = outbuf;
|
char *pOutbuf = outbuf;
|
||||||
|
char *pOutbuf1;
|
||||||
char *pPath1 = NULL;
|
char *pPath1 = NULL;
|
||||||
char *pPath2 = NULL;
|
char *pPath2 = NULL;
|
||||||
int iErr;
|
int iErr;
|
||||||
|
@ -590,10 +595,13 @@ realpathU_failed:
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG_LEAVE(("return 0x%p; // \"%s\"\n", pOutbuf, pOutbuf));
|
DEBUG_LEAVE(("return 0x%p; // \"%s\"\n", pOutbuf, pOutbuf));
|
||||||
if (!outbuf) pOutbuf = realloc(pOutbuf, strlen(pOutbuf) + 1);
|
if (!outbuf) {
|
||||||
|
pOutbuf1 = realloc(pOutbuf, strlen(pOutbuf) + 1);
|
||||||
|
if(pOutbuf1 == NULL && pOutbuf) free(pOutbuf);
|
||||||
|
}
|
||||||
free(pPath1);
|
free(pPath1);
|
||||||
free(pPath2);
|
free(pPath2);
|
||||||
return pOutbuf;
|
return pOutbuf1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* defined(_WIN32) */
|
#endif /* defined(_WIN32) */
|
||||||
|
|
|
@ -116,8 +116,17 @@ void bnCleanupDnodes() {
|
||||||
|
|
||||||
static void bnCheckDnodesSize(int32_t dnodesNum) {
|
static void bnCheckDnodesSize(int32_t dnodesNum) {
|
||||||
if (tsBnDnodes.maxSize <= dnodesNum) {
|
if (tsBnDnodes.maxSize <= dnodesNum) {
|
||||||
tsBnDnodes.maxSize = dnodesNum * 2;
|
int32_t maxSize = dnodesNum * 2;
|
||||||
tsBnDnodes.list = realloc(tsBnDnodes.list, tsBnDnodes.maxSize * sizeof(SDnodeObj *));
|
SDnodeObj** list1 = NULL;
|
||||||
|
int32_t retry = 0;
|
||||||
|
|
||||||
|
while(list1 == NULL && retry++ < 3) {
|
||||||
|
list1 = realloc(tsBnDnodes.list, maxSize * sizeof(SDnodeObj *));
|
||||||
|
}
|
||||||
|
if(list1) {
|
||||||
|
tsBnDnodes.list = list1;
|
||||||
|
tsBnDnodes.maxSize = maxSize;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1527,8 +1527,9 @@ int taos_stmt_prepare(TAOS_STMT* stmt, const char* sql, unsigned long length) {
|
||||||
pCmd->insertParam.insertType = TSDB_QUERY_TYPE_STMT_INSERT;
|
pCmd->insertParam.insertType = TSDB_QUERY_TYPE_STMT_INSERT;
|
||||||
pCmd->insertParam.objectId = pSql->self;
|
pCmd->insertParam.objectId = pSql->self;
|
||||||
|
|
||||||
pSql->sqlstr = realloc(pSql->sqlstr, sqlLen + 1);
|
char* sqlstr = realloc(pSql->sqlstr, sqlLen + 1);
|
||||||
|
if(sqlstr == NULL && pSql->sqlstr) free(pSql->sqlstr);
|
||||||
|
pSql->sqlstr = sqlstr;
|
||||||
if (pSql->sqlstr == NULL) {
|
if (pSql->sqlstr == NULL) {
|
||||||
tscError("%p failed to malloc sql string buffer", pSql);
|
tscError("%p failed to malloc sql string buffer", pSql);
|
||||||
STMT_RET(TSDB_CODE_TSC_OUT_OF_MEMORY);
|
STMT_RET(TSDB_CODE_TSC_OUT_OF_MEMORY);
|
||||||
|
|
|
@ -887,7 +887,9 @@ int taos_validate_sql(TAOS *taos, const char *sql) {
|
||||||
return TSDB_CODE_TSC_EXCEED_SQL_LIMIT;
|
return TSDB_CODE_TSC_EXCEED_SQL_LIMIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
pSql->sqlstr = realloc(pSql->sqlstr, sqlLen + 1);
|
char* sqlstr = realloc(pSql->sqlstr, sqlLen + 1);
|
||||||
|
if(sqlstr == NULL && pSql->sqlstr) free(pSql->sqlstr);
|
||||||
|
pSql->sqlstr = sqlstr;
|
||||||
if (pSql->sqlstr == NULL) {
|
if (pSql->sqlstr == NULL) {
|
||||||
tscError("0x%"PRIx64" failed to malloc sql string buffer", pSql->self);
|
tscError("0x%"PRIx64" failed to malloc sql string buffer", pSql->self);
|
||||||
tfree(pSql);
|
tfree(pSql);
|
||||||
|
|
|
@ -625,8 +625,10 @@ static void setResRawPtrImpl(SSqlRes* pRes, SInternalField* pInfo, int32_t i, bo
|
||||||
|
|
||||||
} else if (convertNchar && pInfo->field.type == TSDB_DATA_TYPE_NCHAR) {
|
} else if (convertNchar && pInfo->field.type == TSDB_DATA_TYPE_NCHAR) {
|
||||||
// convert unicode to native code in a temporary buffer extra one byte for terminated symbol
|
// convert unicode to native code in a temporary buffer extra one byte for terminated symbol
|
||||||
pRes->buffer[i] = realloc(pRes->buffer[i], pInfo->field.bytes * pRes->numOfRows);
|
char* buffer = realloc(pRes->buffer[i], pInfo->field.bytes * pRes->numOfRows);
|
||||||
|
if(buffer == NULL)
|
||||||
|
return ;
|
||||||
|
pRes->buffer[i] = buffer;
|
||||||
// string terminated char for binary data
|
// string terminated char for binary data
|
||||||
memset(pRes->buffer[i], 0, pInfo->field.bytes * pRes->numOfRows);
|
memset(pRes->buffer[i], 0, pInfo->field.bytes * pRes->numOfRows);
|
||||||
|
|
||||||
|
@ -4364,6 +4366,7 @@ int32_t tscCreateTableMetaFromSTableMeta(STableMeta** ppChild, const char* name,
|
||||||
STableMeta* p = NULL;
|
STableMeta* p = NULL;
|
||||||
size_t sz = 0;
|
size_t sz = 0;
|
||||||
STableMeta* pChild = *ppChild;
|
STableMeta* pChild = *ppChild;
|
||||||
|
STableMeta* pChild1;
|
||||||
|
|
||||||
taosHashGetCloneExt(tscTableMetaMap, pChild->sTableName, strnlen(pChild->sTableName, TSDB_TABLE_FNAME_LEN), NULL, (void **)&p, &sz);
|
taosHashGetCloneExt(tscTableMetaMap, pChild->sTableName, strnlen(pChild->sTableName, TSDB_TABLE_FNAME_LEN), NULL, (void **)&p, &sz);
|
||||||
|
|
||||||
|
@ -4374,7 +4377,10 @@ int32_t tscCreateTableMetaFromSTableMeta(STableMeta** ppChild, const char* name,
|
||||||
int32_t totalBytes = (p->tableInfo.numOfColumns + p->tableInfo.numOfTags) * sizeof(SSchema);
|
int32_t totalBytes = (p->tableInfo.numOfColumns + p->tableInfo.numOfTags) * sizeof(SSchema);
|
||||||
int32_t tableMetaSize = sizeof(STableMeta) + totalBytes;
|
int32_t tableMetaSize = sizeof(STableMeta) + totalBytes;
|
||||||
if (*tableMetaCapacity < tableMetaSize) {
|
if (*tableMetaCapacity < tableMetaSize) {
|
||||||
pChild = realloc(pChild, tableMetaSize);
|
pChild1 = realloc(pChild, tableMetaSize);
|
||||||
|
if(pChild1 == NULL)
|
||||||
|
return -1;
|
||||||
|
pChild = pChild1;
|
||||||
*tableMetaCapacity = (size_t)tableMetaSize;
|
*tableMetaCapacity = (size_t)tableMetaSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -547,8 +547,9 @@ SKVRow tdGetKVRowFromBuilder(SKVRowBuilder *pBuilder);
|
||||||
static FORCE_INLINE int tdAddColToKVRow(SKVRowBuilder *pBuilder, int16_t colId, int8_t type, void *value) {
|
static FORCE_INLINE int tdAddColToKVRow(SKVRowBuilder *pBuilder, int16_t colId, int8_t type, void *value) {
|
||||||
if (pBuilder->nCols >= pBuilder->tCols) {
|
if (pBuilder->nCols >= pBuilder->tCols) {
|
||||||
pBuilder->tCols *= 2;
|
pBuilder->tCols *= 2;
|
||||||
pBuilder->pColIdx = (SColIdx *)realloc((void *)(pBuilder->pColIdx), sizeof(SColIdx) * pBuilder->tCols);
|
SColIdx* pColIdx = (SColIdx *)realloc((void *)(pBuilder->pColIdx), sizeof(SColIdx) * pBuilder->tCols);
|
||||||
if (pBuilder->pColIdx == NULL) return -1;
|
if (pColIdx == NULL) return -1;
|
||||||
|
pBuilder->pColIdx = pColIdx;
|
||||||
}
|
}
|
||||||
|
|
||||||
pBuilder->pColIdx[pBuilder->nCols].colId = colId;
|
pBuilder->pColIdx[pBuilder->nCols].colId = colId;
|
||||||
|
@ -561,8 +562,9 @@ static FORCE_INLINE int tdAddColToKVRow(SKVRowBuilder *pBuilder, int16_t colId,
|
||||||
while (tlen > pBuilder->alloc - pBuilder->size) {
|
while (tlen > pBuilder->alloc - pBuilder->size) {
|
||||||
pBuilder->alloc *= 2;
|
pBuilder->alloc *= 2;
|
||||||
}
|
}
|
||||||
pBuilder->buf = realloc(pBuilder->buf, pBuilder->alloc);
|
void* buf = realloc(pBuilder->buf, pBuilder->alloc);
|
||||||
if (pBuilder->buf == NULL) return -1;
|
if (buf == NULL) return -1;
|
||||||
|
pBuilder->buf = buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(POINTER_SHIFT(pBuilder->buf, pBuilder->size), value, tlen);
|
memcpy(POINTER_SHIFT(pBuilder->buf, pBuilder->size), value, tlen);
|
||||||
|
|
|
@ -138,8 +138,9 @@ int tdAddColToSchema(STSchemaBuilder *pBuilder, int8_t type, int16_t colId, int1
|
||||||
|
|
||||||
if (pBuilder->nCols >= pBuilder->tCols) {
|
if (pBuilder->nCols >= pBuilder->tCols) {
|
||||||
pBuilder->tCols *= 2;
|
pBuilder->tCols *= 2;
|
||||||
pBuilder->columns = (STColumn *)realloc(pBuilder->columns, sizeof(STColumn) * pBuilder->tCols);
|
STColumn* columns = (STColumn *)realloc(pBuilder->columns, sizeof(STColumn) * pBuilder->tCols);
|
||||||
if (pBuilder->columns == NULL) return -1;
|
if (columns == NULL) return -1;
|
||||||
|
pBuilder->columns = columns;
|
||||||
}
|
}
|
||||||
|
|
||||||
STColumn *pCol = &(pBuilder->columns[pBuilder->nCols]);
|
STColumn *pCol = &(pBuilder->columns[pBuilder->nCols]);
|
||||||
|
|
|
@ -72,12 +72,13 @@ static int32_t shellShowTables(TAOS *con, char *db) {
|
||||||
int32_t tbIndex = tbNum++;
|
int32_t tbIndex = tbNum++;
|
||||||
if (tbMallocNum < tbNum) {
|
if (tbMallocNum < tbNum) {
|
||||||
tbMallocNum = (tbMallocNum * 2 + 1);
|
tbMallocNum = (tbMallocNum * 2 + 1);
|
||||||
tbNames = realloc(tbNames, tbMallocNum * sizeof(char *));
|
char** tbNames1 = realloc(tbNames, tbMallocNum * sizeof(char *));
|
||||||
if (tbNames == NULL) {
|
if (tbNames1 == NULL) {
|
||||||
fprintf(stdout, "failed to malloc tablenames, num:%d\n", tbMallocNum);
|
fprintf(stdout, "failed to malloc tablenames, num:%d\n", tbMallocNum);
|
||||||
code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
tbNames = tbNames1;
|
||||||
}
|
}
|
||||||
|
|
||||||
tbNames[tbIndex] = malloc(TSDB_TABLE_NAME_LEN);
|
tbNames[tbIndex] = malloc(TSDB_TABLE_NAME_LEN);
|
||||||
|
|
|
@ -149,7 +149,10 @@ float* read_float(const char* inFile, int* pcount){
|
||||||
//printf(" buff=%s float=%.50f \n ", buf, floats[fi]);
|
//printf(" buff=%s float=%.50f \n ", buf, floats[fi]);
|
||||||
if ( ++fi == malloc_cnt ) {
|
if ( ++fi == malloc_cnt ) {
|
||||||
malloc_cnt += 100000;
|
malloc_cnt += 100000;
|
||||||
floats = realloc(floats, malloc_cnt*sizeof(float));
|
float* floats1 = realloc(floats, malloc_cnt*sizeof(float));
|
||||||
|
if(floats1 == NULL)
|
||||||
|
break;
|
||||||
|
floats = floats1;
|
||||||
}
|
}
|
||||||
memset(buf, 0, sizeof(buf));
|
memset(buf, 0, sizeof(buf));
|
||||||
}
|
}
|
||||||
|
|
|
@ -2921,10 +2921,11 @@ static SMultiTableMeta* ensureMsgBufferSpace(SMultiTableMeta *pMultiMeta, SArray
|
||||||
(*totalMallocLen) *= 2;
|
(*totalMallocLen) *= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
pMultiMeta = realloc(pMultiMeta, *totalMallocLen);
|
SMultiTableMeta* pMultiMeta1 = realloc(pMultiMeta, *totalMallocLen);
|
||||||
if (pMultiMeta == NULL) {
|
if (pMultiMeta1 == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
pMultiMeta = pMultiMeta1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return pMultiMeta;
|
return pMultiMeta;
|
||||||
|
|
|
@ -504,8 +504,9 @@ void * taosTRealloc(void *ptr, size_t size) {
|
||||||
|
|
||||||
void * tptr = (void *)((char *)ptr - sizeof(size_t));
|
void * tptr = (void *)((char *)ptr - sizeof(size_t));
|
||||||
size_t tsize = size + sizeof(size_t);
|
size_t tsize = size + sizeof(size_t);
|
||||||
tptr = realloc(tptr, tsize);
|
void* tptr1 = realloc(tptr, tsize);
|
||||||
if (tptr == NULL) return NULL;
|
if (tptr1 == NULL) return NULL;
|
||||||
|
tptr = tptr1;
|
||||||
|
|
||||||
*(size_t *)tptr = size;
|
*(size_t *)tptr = size;
|
||||||
|
|
||||||
|
|
|
@ -81,11 +81,13 @@ int32_t getstr(char **lineptr, size_t *n, FILE *stream, char terminator, int32_t
|
||||||
*n += MIN_CHUNK;
|
*n += MIN_CHUNK;
|
||||||
|
|
||||||
nchars_avail = (int32_t)(*n + *lineptr - read_pos);
|
nchars_avail = (int32_t)(*n + *lineptr - read_pos);
|
||||||
*lineptr = realloc(*lineptr, *n);
|
char* lineptr1 = realloc(*lineptr, *n);
|
||||||
if (!*lineptr) {
|
if (!lineptr1) {
|
||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
*lineptr = lineptr1;
|
||||||
|
|
||||||
read_pos = *n - nchars_avail + *lineptr;
|
read_pos = *n - nchars_avail + *lineptr;
|
||||||
assert((*lineptr + *n) == (read_pos + nchars_avail));
|
assert((*lineptr + *n) == (read_pos + nchars_avail));
|
||||||
}
|
}
|
||||||
|
|
|
@ -223,10 +223,13 @@ static STSGroupBlockInfoEx* addOneGroupInfo(STSBuf* pTSBuf, int32_t id) {
|
||||||
static void shrinkBuffer(STSList* ptsData) {
|
static void shrinkBuffer(STSList* ptsData) {
|
||||||
// shrink tmp buffer size if it consumes too many memory compared to the pre-defined size
|
// shrink tmp buffer size if it consumes too many memory compared to the pre-defined size
|
||||||
if (ptsData->allocSize >= ptsData->threshold * 2) {
|
if (ptsData->allocSize >= ptsData->threshold * 2) {
|
||||||
ptsData->rawBuf = realloc(ptsData->rawBuf, MEM_BUF_SIZE);
|
char* rawBuf = realloc(ptsData->rawBuf, MEM_BUF_SIZE);
|
||||||
|
if(rawBuf) {
|
||||||
|
ptsData->rawBuf = rawBuf;
|
||||||
ptsData->allocSize = MEM_BUF_SIZE;
|
ptsData->allocSize = MEM_BUF_SIZE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int32_t getTagAreaLength(tVariant* pa) {
|
static int32_t getTagAreaLength(tVariant* pa) {
|
||||||
int32_t t = sizeof(pa->nLen) * 2 + sizeof(pa->nType);
|
int32_t t = sizeof(pa->nLen) * 2 + sizeof(pa->nType);
|
||||||
|
|
Loading…
Reference in New Issue