OJ专题(一)



OJ专题(一)

最近大家都开始使用string.h头文件里面的一些函数啦,而且声明的变量也越来越大,那么,这样会出现什么问题呢?要注意些什么呢?现在我给大家整理一下。

我们发现,最近OJ上测试时经常会造成segmentation fault,产生core dump等错误,经过网上搜集资料、结合OJ服务器机器属性(据说是32位的Linux)以及大家写的代码中可以发现,可能原因有如下几个

一、 内存访问越界

1. 使用错误的下标,导致数组访问越界。在测试某些测点(大家没想到的一些临界测点)时,可能会产生大于数组长度,或者小于0的数组下标,这样,大家在自己机器上测试时不会发现,一旦用OJ评测,就会发生运行时错误。

2. 搜索字符串时,依靠字符串结束符来判断字符串是否结束,但是字符串没有正常的使用结束符

3. 使用strcpy, strcat, sprintf, strcmp, strcasecmp等字符串操作函数,将目标字符串读/写爆。应该使用strncpy, strlcpy, strncat, strlcat, snprintf, strncmp, strncasecmp等函数防止读写越界。以后一定记住用后面几个函数!即使前面几个可以自动添加’\0’来作为结束标志,但有的时候如果不注意就会超出数组范围,这样,就会发生运行时错误。最近大家使用string.h比较频繁,一旦要注意呀

二、 堆栈溢出。记住,不要定义特别大的局部变量(也就是在函数里面,包括main函数,具体多大呢。。大家自己去试试,试到程序奔溃为止。),因为局部变量都分配在栈上这样容易造成堆栈溢出,破坏系统的栈和堆结构,导致出现莫名其妙的错误。大家最近定义的变量都非常大。所以我建议大家首先要选择好的算法,能节省更多的时空(时间与空间),然后是准确估计具体要用到多少的空间,比如题意有给出“每个单词最多10个字符”,那么我们就在每个单词的那一维定义11个字符,这样既符合题意,又不会溢出。最后,实在没办法的,我们就定义成全局变量!也就是函数外面,不要定义在函数里面(包括main函数),当然,这个和机器、编译器也有一些关系,有些编译器给函数分配的堆栈就特别大,所以有的时候就能测试通过。

其它大家未学习到、未涉及到的具体有:

1. 非法指针 

a) 使用空指针

b) 随意使用指针转换。一个指向一段内存的指针,除非确定这段内存原先就分配为某种结构或类型,或者这种结构或类型的数组,否则不要将它转换为这种结构或类型的指针,而应该将这段内存拷贝到一个这种结构或类型中,再访问这个结构或类型。这是因为如果这段内存的开始地址不是按照这种结构或类型对齐的,那么访问它时就很容易因为bus errorcore dump.

2. 多线程程序使用了线程不安全的函数。

3. 多线程读写的数据未加锁保护。对于会被多个线程同时访问的全局数据,应该注意加锁保护,否则很容易造成core dump

 

综上所述:我建议大家以后做题学会以下几个方面:

1. 多想想一些临界的测点。比如要求输入字符串,那么就试试一个字符的能不能有效。

2. 学会调试,查看调试过程中变量的变化情况。

3. 学会文件操作或者重定向操作,这样以后测试的时候就不麻烦啦!一个命令就搞定,不用一个个字符输入。如果实在要。。那就学会在控制台复制粘贴好了。。

 

通知一:C语言积分赛快开始啦~大家抓紧时间准备吧,这可能是大家大学刚进来参加的第一个学术类竞赛,也是一个比较有“营养价值”的比赛,拿奖不仅有加综测,还有机会期末加分哦。。大家准备好了吗!

通知二:招募几位对OJ有强烈兴趣的同学,帮忙管理OJ,主要负责的事项有:出题(只要负责写代码出测点就好了~+ 管理测点->给有需要的同学。想参加的同学发送短信“姓名+班级+学号”到18120775090,到时候按人数进行筛选~

 

最后:祝大家生活健康,学习进步!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值