【大家来找茬】不知道到这发个这样的帖子合不合适呀。。。各位C/C++大牛们快来呀~~~~~~~~~

俺是小王子 2014-01-07 09:47:07
玩个大家来找茬的游戏

呵呵,不过这个游戏还真没QQ游戏里的那个那么好玩~~~~
这样的,我贴出几段代码,上面有各个不同的功能,其中至少有一段代码存在漏洞,会导致程序陷入死循环或者什么的。

先说要求:只能使用基本操作去实现string.h库中的一些函数功能。前提是不能包含string.h。

代码片段一: 获取字符串长度
unsigned int strlenth(char *s)  
{
unsigned int lenth = 0;
if(!s){
return 0;
}
while(*(s++)){
lenth++;
}

return lenth;
}



代码片段二:字符串拷贝
void strcopy(char **target, char *source) 
{
unsigned length = strlenth(source);
*target = (char*)malloc(length);
**target = 0;
if(!source || !*target){
return;
}
unsigned int i = 0;

while(source[i]){
(*target)[i] = source[i++];
}
(*target)[i] = '\0';


}



代码片段三: 字符串比较,s>t,则返回1;s=t,则返回0;s<t,则返回-1
int strcompare(char *s, char *t)  
{

if(!s && !t){
return 0;
}
if(s && !t){
return 1;
}
if(!s && t){
return -1;
}
while(*s || *t){
if(*s > *t){
return 1;
}else if(*s < *t){
return -1;
}

s++;
t++;

}

return 0;
}


代码片段四:字符串连接,将字符串t接到s后面,x为连接后的新串
void strcombine(char **x, char *s, char *t)  
{

if(!s){
*s = '\0';
}
if(!t){
*t = '\0';
}
unsigned int length = strlenth(s) + strlenth(t);
*x = (char*)malloc(length);
**x = '\0';
unsigned int i = 0;
while(*s){
(*x)[i++] = *(s++);
}
while(*t){
(*x)[i++] = *(t++);
}
(*x)[i] = '\0';

}


代码片段五: 字符串截取,从第index个字符开始,截取lenth长度的字符串,并输出到字符串t
void strcatch(char *s, unsigned int index, unsigned int lenth, char **t) 
{

unsigned int length = strlenth(s);
if(!s || lenth > length - index || lenth < 1 || index > length){
return;
}
*t = (char*)malloc(lenth);
**t = 0;

unsigned int i = index, j= 0;
for(; i <index + lenth; i++){
(*t)[j++] = s[i];
}
(*t)[j] = '\0';


}


代码片段六: 字符串子串查找,如果子串sub在s中存在,则返回1,否则返回0
bool strsubstr(char *s, char *sub) 
{
bool result = 0;


if(!s || !sub){
return 0;
}
unsigned int i = 0, j = 0;
unsigned int length1 = strlenth(s);
unsigned int length2 = strlenth(sub);
if(length1 == 0 && length2 == 0){
return 1;
}
for(; i < length1; i++){
if(s[i] == sub[j++]){
if(j == length2){
result = 1;
break;
}
continue;
}else{
j = 0;
}
}

return result;
}


散粉。。。。
...全文
138 16 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
俺是小王子 2014-01-07
  • 打赏
  • 举报
回复
引用 10 楼 vipcxj 的回复:
我之所以说LZ分多得没处花是因为既然这代码是LZ自己用来练手的,那么遇到问题就应该自己常识解决,这样水平才能提高,一味依靠别人,那就是在浪费时间
http://bbs.csdn.net/topics/390688307 分已散,请去接分吧
俺是小王子 2014-01-07
  • 打赏
  • 举报
回复
引用 14 楼 vipcxj 的回复:
[quote=引用 13 楼 benma378 的回复:] [quote=引用 9 楼 vipcxj 的回复:] 又是一段明显初学者写的代码~

int strcompare(char *s, char *t)  
{
     
    if(!s && !t){ 
        return 0;
    }
    if(s && !t){
        return 1;
    }
    if(!s && t){
        return -1;
    }
    while(*s || *t){ //这个条件是错误滴,*s && *t
        if(*s > *t){
            return 1;
        }else if(*s < *t){
            return -1;
        }
        s++;
        t++;
    }

    //可不能直接返回0
    if (*s)
       return 1;
    else if (*t)
       return -1;
    else
       return 0;
}
关于这个条件,我觉得是或关系,因为子串肯定短一些,必须完全遍历一遍父串吧。其实子串可以不要,放在循环里判断更好一些[/quote] 你这种逻辑就是非常有问题的,如果是或关系,就有可能有一个超出字符串范围,一个还在范围内,但出不了循环,仍旧继续在迭代,导致的结果是必然会访问到字符串上无效的位置。其实你只要考虑到循环访问一个字符串,绝对要保证访问的都是有效位置就不会出这种问题了。我估计你的思路是妄图走捷径,希望在循环内一次解决,其实编程最好不要有捷径的想法,情愿事后优化也不要在编写的时候想着直接写出最好最简洁的方法,往往这样花的时间更长,错误率更高。[/quote] 你应该是一个比较有经验的程序员了。。。确实是这样的哈,刚刚想删回复也删不了,想编辑也编辑不了了。确实没有思考清楚就回复了。 嗯,昨晚写的程序,发现时间越晚可能错误率也高。现在我来看着代码,感觉确实思路不清晰,这是一个修炼的过程。我还有很长的路要走!谢谢!我会把可用分散在灌水区里,希望你来拿。。呵呵,兑现我的承诺。好像不能直接转的吧
vipcxj 2014-01-07
  • 打赏
  • 举报
回复
引用 13 楼 benma378 的回复:
[quote=引用 9 楼 vipcxj 的回复:] 又是一段明显初学者写的代码~

int strcompare(char *s, char *t)  
{
     
    if(!s && !t){ 
        return 0;
    }
    if(s && !t){
        return 1;
    }
    if(!s && t){
        return -1;
    }
    while(*s || *t){ //这个条件是错误滴,*s && *t
        if(*s > *t){
            return 1;
        }else if(*s < *t){
            return -1;
        }
        s++;
        t++;
    }

    //可不能直接返回0
    if (*s)
       return 1;
    else if (*t)
       return -1;
    else
       return 0;
}
关于这个条件,我觉得是或关系,因为子串肯定短一些,必须完全遍历一遍父串吧。其实子串可以不要,放在循环里判断更好一些[/quote] 你这种逻辑就是非常有问题的,如果是或关系,就有可能有一个超出字符串范围,一个还在范围内,但出不了循环,仍旧继续在迭代,导致的结果是必然会访问到字符串上无效的位置。其实你只要考虑到循环访问一个字符串,绝对要保证访问的都是有效位置就不会出这种问题了。我估计你的思路是妄图走捷径,希望在循环内一次解决,其实编程最好不要有捷径的想法,情愿事后优化也不要在编写的时候想着直接写出最好最简洁的方法,往往这样花的时间更长,错误率更高。
俺是小王子 2014-01-07
  • 打赏
  • 举报
回复
引用 9 楼 vipcxj 的回复:
又是一段明显初学者写的代码~

int strcompare(char *s, char *t)  
{
     
    if(!s && !t){ 
        return 0;
    }
    if(s && !t){
        return 1;
    }
    if(!s && t){
        return -1;
    }
    while(*s || *t){ //这个条件是错误滴,*s && *t
        if(*s > *t){
            return 1;
        }else if(*s < *t){
            return -1;
        }
        s++;
        t++;
    }

    //可不能直接返回0
    if (*s)
       return 1;
    else if (*t)
       return -1;
    else
       return 0;
}
关于这个条件,我觉得是或关系,因为子串肯定短一些,必须完全遍历一遍父串吧。其实子串可以不要,放在循环里判断更好一些
俺是小王子 2014-01-07
  • 打赏
  • 举报
回复
引用 2 楼 vipcxj 的回复:

void strcopy(char **target, char *source) 
{
    if(!source){
        return;
    }
    unsigned length = strlenth(source);
    *target = (char*)malloc(length + 1); //这里要改
    if(*target){
        return;
    }
    unsigned int i = 0;
 
    for(; i<length; ++i){
        (*target)[i] = source[i];
    }
    (*target)[i] = '\0';
}
先修正一个在看下面的
length+1确实是的,但是你说在哪种情况下回导致死循环呢还是越界访问?为啥一定要把while改成for呢?while不是更加简洁吗?
俺是小王子 2014-01-07
  • 打赏
  • 举报
回复
引用 10 楼 vipcxj 的回复:
我之所以说LZ分多得没处花是因为既然这代码是LZ自己用来练手的,那么遇到问题就应该自己常识解决,这样水平才能提高,一味依靠别人,那就是在浪费时间
这话在理,遇到问题应该先自己思考,google之,再思考之。。。 说实话,Java和C、C++差别还是蛮大的。很多繁琐的细节问题Java都不需要去反复考虑,而C、C++就不一样,存在这复杂的指针、内存问题。 当然,从算法的严谨度来说,这样的代码确实太嫩了。但这岂是一朝一夕的事情? 这是一道OJ上的题,由于两年多没接触过C、C++,只有靠大一那点底子了。(当然,你会说这是我不主动学习的借口)当时我提交的时候,自己的用例都通过了,就是不知道为啥OJ上跑就超时了,知道肯定是自己代码问题,但一时找不到自己漏洞到底在哪?对C、C++细节确实不是熟悉,一个从没系统学习过的能熟悉到哪去呢? 当然,如果是要我学习的话,我不会这样学的,应该是从最基础的开始,一步一步来。总之,你猜对了
vipcxj 2014-01-07
  • 打赏
  • 举报
回复
我之所以说LZ分多得没处花是因为既然这代码是LZ自己用来练手的,那么遇到问题就应该自己常识解决,这样水平才能提高,一味依靠别人,那就是在浪费时间
vipcxj 2014-01-07
  • 打赏
  • 举报
回复
又是一段明显初学者写的代码~

int strcompare(char *s, char *t)  
{
     
    if(!s && !t){ 
        return 0;
    }
    if(s && !t){
        return 1;
    }
    if(!s && t){
        return -1;
    }
    while(*s || *t){ //这个条件是错误滴,*s && *t
        if(*s > *t){
            return 1;
        }else if(*s < *t){
            return -1;
        }
        s++;
        t++;
    }

    //可不能直接返回0
    if (*s)
       return 1;
    else if (*t)
       return -1;
    else
       return 0;
}
俺是小王子 2014-01-07
  • 打赏
  • 举报
回复
引用 6 楼 vipcxj 的回复:
老实说看着这些代码的水平,我估计这根本就是LZ自己写来练手的吧,但又不好意思不耻下问,就出此下策了,不过看在LZ的分多得没处花的份上,我还是来帮帮LZ吧
好吧,我确实没啥水平,因为代码总量不超过10w行。。学生党嘛。。。 请友情提示一下代码问题在哪?比如代码风格啊,思路啊,清晰度,可靠性等等这些问题。 当然C/C++用法方面的就算了,我这两年来一直写Java,最近才接触这些东西。主要是算法评价和思路
vipcxj 2014-01-07
  • 打赏
  • 举报
回复
引用 5 楼 benma378 的回复:
[quote=引用 2 楼 vipcxj 的回复:]

void strcopy(char **target, char *source) 
{
    if(!source){
        return;
    }
    unsigned length = strlenth(source);
    *target = (char*)malloc(length + 1); //这里要改
    if(*target){
        return;
    }
    unsigned int i = 0;
 
    for(; i<length; ++i){
        (*target)[i] = source[i];
    }
    (*target)[i] = '\0';
}
先修正一个在看下面的
引用 4 楼 benma378 的回复:
额,忘了说了,每找出一个,必须说出理由和可行的测试用例。。每一个奖励可用分100分
请说出理由[/quote] 你比对一下不就能看出问题了,第一个问题,你为字符串申请内存要length+1,这是常识吧,第二个问题,你后面空指针的判断,其实这应该第一步判断吧,你后判断也是依赖于你strlength里面判断过,不然就死定了。后面的循环,你既然已经搞到了length,为啥还要用while,直接for不就得了。
vipcxj 2014-01-07
  • 打赏
  • 举报
回复
老实说看着这些代码的水平,我估计这根本就是LZ自己写来练手的吧,但又不好意思不耻下问,就出此下策了,不过看在LZ的分多得没处花的份上,我还是来帮帮LZ吧
俺是小王子 2014-01-07
  • 打赏
  • 举报
回复
引用 2 楼 vipcxj 的回复:

void strcopy(char **target, char *source) 
{
    if(!source){
        return;
    }
    unsigned length = strlenth(source);
    *target = (char*)malloc(length + 1); //这里要改
    if(*target){
        return;
    }
    unsigned int i = 0;
 
    for(; i<length; ++i){
        (*target)[i] = source[i];
    }
    (*target)[i] = '\0';
}
先修正一个在看下面的
引用 4 楼 benma378 的回复:
额,忘了说了,每找出一个,必须说出理由和可行的测试用例。。每一个奖励可用分100分
请说出理由
俺是小王子 2014-01-07
  • 打赏
  • 举报
回复
额,忘了说了,每找出一个,必须说出理由和可行的测试用例。。每一个奖励可用分100分
俺是小王子 2014-01-07
  • 打赏
  • 举报
回复
引用 1 楼 derekrose 的回复:
人艰不拆
vipcxj 2014-01-07
  • 打赏
  • 举报
回复

void strcopy(char **target, char *source) 
{
    if(!source){
        return;
    }
    unsigned length = strlenth(source);
    *target = (char*)malloc(length + 1); //这里要改
    if(*target){
        return;
    }
    unsigned int i = 0;
 
    for(; i<length; ++i){
        (*target)[i] = source[i];
    }
    (*target)[i] = '\0';
}
先修正一个在看下面的
derekrose 2014-01-07
  • 打赏
  • 举报
回复
人艰不拆

70,023

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧