C++ C代码-需要澄清有效性
嗨,我已经写了一个基于需求的代码 (第1区第6区第2区第30区第3区第16区第4区第1区第6区第7区第2区第8区第1区)。。。。。 这是一个数据桶(8个字段)。我们一次将收到20个桶,即总共160个字段。 我需要根据预定义条件获取字段3、字段7和字段8的值。 如果输入参数为N,则从第一个桶中取出三个字段,如果为Y,则需要 从除第一个桶以外的任何其他桶中取出三个字段。 如果argumnet是Y,那么我需要逐个扫描所有20个bucket并进行检查 bucket的第一个字段不等于0,如果为true,则获取该bucket的三个字段并退出。 我已经写了代码,它也工作得很好。但是我不太相信它是有效的。 我担心某个时候会崩溃。请建议下面是代码C++ C代码-需要澄清有效性,c++,c,unix,gdb,dbx,C++,C,Unix,Gdb,Dbx,嗨,我已经写了一个基于需求的代码 (第1区第6区第2区第30区第3区第16区第4区第1区第6区第7区第2区第8区第1区)。。。。。 这是一个数据桶(8个字段)。我们一次将收到20个桶,即总共160个字段。 我需要根据预定义条件获取字段3、字段7和字段8的值。 如果输入参数为N,则从第一个桶中取出三个字段,如果为Y,则需要 从除第一个桶以外的任何其他桶中取出三个字段。 如果argumnet是Y,那么我需要逐个扫描所有20个bucket并进行检查 bucket的第一个字段不等于0,如果为true,则
int CMI9_auxc_parse_balance_info(char *i_balance_info,char *i_use_balance_ind,char *o_balance,char *o_balance_change,char *o_balance_sign
)
{
char *pch = NULL;
char *balance_id[MAX_BUCKETS] = {NULL};
char balance_info[BALANCE_INFO_FIELD_MAX_LENTH] = {0};
char *str[160] = {NULL};
int i=0,j=0,b_id=0,b_ind=0,bc_ind=0,bs_ind=0,rc;
int total_bukets ;
memset(balance_info,' ',BALANCE_INFO_FIELD_MAX_LENTH);
memcpy(balance_info,i_balance_info,BALANCE_INFO_FIELD_MAX_LENTH);
//balance_info[BALANCE_INFO_FIELD_MAX_LENTH]='\0';
pch = strtok (balance_info,"*");
while (pch != NULL && i < 160)
{
str[i]=(char*)malloc(strlen(pch) + 1);
strcpy(str[i],pch);
pch = strtok (NULL, "*");
i++;
}
total_bukets = i/8 ;
for (j=0;str[b_id]!=NULL,j<total_bukets;j++)
{
balance_id[j]=str[b_id];
b_id=b_id+8;
}
if (!memcmp(i_use_balance_ind,"Y",1))
{
if (atoi(balance_id[0])==1)
{
memcpy(o_balance,str[2],16);
memcpy(o_balance_change,str[3],16);
memcpy(o_balance_sign,str[7],1);
for(i=0;i<160;i++)
free(str[i]);
return 1;
}
else
{
for(i=0;i<160;i++)
free(str[i]);
return 0;
}
}
else if (!memcmp(i_use_balance_ind,"N",1))
{
for (j=1;balance_id[j]!=NULL,j<MAX_BUCKETS;j++)
{
b_ind=(j*8)+2;
bc_ind=(j*8)+3;
bs_ind=(j*8)+7;
if (atoi(balance_id[j])!=1 && atoi( str[bc_ind] )!=0)
{
memcpy(o_balance,str[b_ind],16);
memcpy(o_balance_change,str[bc_ind],16);
memcpy(o_balance_sign,str[bs_ind],1);
for(i=0;i<160;i++)
free(str[i]);
return 1;
}
}
for(i=0;i<160;i++)
free(str[i]);
return 0;
}
for(i=0;i<160;i++)
free(str[i]);
return 0;
}
int CMI9_auxc_parse_balance_info(字符*i_balance_info,字符*i_use_balance_ind,字符*o_balance,字符*o_balance_change,字符*o_balance_sign
)
{
char*pch=NULL;
char*balance_id[MAX_bucket]={NULL};
字符余额信息[余额信息字段最大长度]={0};
char*str[160]={NULL};
int i=0,j=0,b_id=0,b_ind=0,bc_ind=0,bs_ind=0,rc;
国际总预算;
memset(余额信息),余额信息字段最大长度;
memcpy(余额信息、i余额信息、余额信息字段、最大长度);
//余额信息[余额信息字段最大长度]='\0';
pch=strtok(余额信息,“*”);
而(pch!=NULL&&i<160)
{
str[i]=(char*)malloc(strlen(pch)+1);
strcpy(str[i],pch);
pch=strtok(空,“*”);
i++;
}
总数=1/8;
对于(j=0;str[b_id]!=NULL,j我的感觉是这段代码非常脆弱。如果输入正确(我不建议为您进行桌面检查),它可能会很好地工作,但如果输入错误,它将崩溃并烧掉,或者给出误导性的结果
您是否测试过意外输入?例如:
- 假设i\u balance\u info为空
- 假设我的余额信息是“”
- 假设输入字符串中的项少于8项,这行代码将做什么
memcpy(o_balance_sign,str[7],1);
- 假设str[3]中的项长度小于16个字符,那么这行代码将做什么
memcpy(o_balance_change,str[3],16);
我编写此类代码的方法是防止所有此类事件的发生语句,我通常会编写显式输入验证,并在错误时返回错误。这里的问题是,接口似乎不允许出现错误输入的任何可能性。我很难阅读您的代码,但FWIW我添加了一些注释,HTH:
// do shorter functions, long functions are harder to follow and make errors harder to spot
// document all your variables, at the very least your function parameters
// also what the function is suppose to do and what it expects as input
int CMI9_auxc_parse_balance_info
(
char *i_balance_info,
char *i_use_balance_ind,
char *o_balance,
char *o_balance_change,
char *o_balance_sign
)
{
char *balance_id[MAX_BUCKETS] = {NULL};
char balance_info[BALANCE_INFO_FIELD_MAX_LENTH] = {0};
char *str[160] = {NULL};
int i=0,j=0,b_id=0,b_ind=0,bc_ind=0,bs_ind=0,rc;
int total_bukets=0; // good practice to initialize all variables
//
// check for null pointers in your arguments, and do sanity checks for any
// calculations
// also move variable declarations to just before they are needed
//
memset(balance_info,' ',BALANCE_INFO_FIELD_MAX_LENTH);
memcpy(balance_info,i_balance_info,BALANCE_INFO_FIELD_MAX_LENTH);
//balance_info[BALANCE_INFO_FIELD_MAX_LENTH]='\0'; // should be BALANCE_INFO_FIELD_MAX_LENTH-1
char *pch = strtok (balance_info,"*"); // this will potentially crash since no ending \0
while (pch != NULL && i < 160)
{
str[i]=(char*)malloc(strlen(pch) + 1);
strcpy(str[i],pch);
pch = strtok (NULL, "*");
i++;
}
total_bukets = i/8 ;
// you have declared char*str[160] check if enough b_id < 160
// asserts are helpful if nothing else assert( b_id < 160 );
for (j=0;str[b_id]!=NULL,j<total_bukets;j++)
{
balance_id[j]=str[b_id];
b_id=b_id+8;
}
// don't use memcmp, if ('y'==i_use_balance_ind[0]) is better
if (!memcmp(i_use_balance_ind,"Y",1))
{
// atoi needs balance_id str to end with \0 has it?
if (atoi(balance_id[0])==1)
{
// length assumptions and memcpy when its only one byte
memcpy(o_balance,str[2],16);
memcpy(o_balance_change,str[3],16);
memcpy(o_balance_sign,str[7],1);
for(i=0;i<160;i++)
free(str[i]);
return 1;
}
else
{
for(i=0;i<160;i++)
free(str[i]);
return 0;
}
}
// if ('N'==i_use_balance_ind[0])
else if (!memcmp(i_use_balance_ind,"N",1))
{
// here I get a headache, this looks just at first glance risky.
for (j=1;balance_id[j]!=NULL,j<MAX_BUCKETS;j++)
{
b_ind=(j*8)+2;
bc_ind=(j*8)+3;
bs_ind=(j*8)+7;
if (atoi(balance_id[j])!=1 && atoi( str[bc_ind] )!=0)
{
// length assumptions and memcpy when its only one byte
// here u assume strlen(str[b_ind])>15 including \0
memcpy(o_balance,str[b_ind],16);
// here u assume strlen(str[bc_ind])>15 including \0
memcpy(o_balance_change,str[bc_ind],16);
// here, besides length assumption you could use a simple assignment
// since its one byte
memcpy(o_balance_sign,str[bs_ind],1);
// a common practice is to set pointers that are freed to NULL.
// maybe not necessary here since u return
for(i=0;i<160;i++)
free(str[i]);
return 1;
}
}
// suggestion do one function that frees your pointers to avoid dupl
for(i=0;i<160;i++)
free(str[i]);
return 0;
}
for(i=0;i<160;i++)
free(str[i]);
return 0;
}
(或者不管你想做什么)@dgna,首先我要确认的是,在一个存储桶中,我永远不会收到少于8个字段。唯一的问题是,在acse中,我有时可能不会收到20个存储桶。其次,balnace信息永远不会为null。由于我在检查其非null后从其他函数传递它,代码的本质是它在新的上下文和新的假设。防御性编码保护您免受调用您的东西的更改(和bug)。如果您担心性能开销,那么使用ASSERT(),它可以在开发过程中使用,并为生产编译
int foo( input* inbalance, output* outbalance )