一、概述
数组越界是移动端、服务器最常见的越界之一,虽然有些语言加了保护,但还是很多会导致Crash。例如,OC、C等。
通过学习一些越界的坑,无疑可以提高自己代码逻辑严谨性,故汇总于此。
二、数组越界汇总
2.1、执行 --i
代码时
- 因为 i 是无符号整数,所以
当i=0,执行--i
,会出现无穷大的数,导致越界。
NSArray *array = @[@1, @2, @3, @4];
for (NSUInteger i = array.count - 1; i >= 0; --i) {
NSLog(@"%@", array[i]);
}
- 如果 i 是有符号整数,则没有问题。
NSArray *array = @[@1, @2, @3, @4];
for (NSInteger i = array.count - 1; i >= 0; --i) {
NSLog(@"%@", array[i]);
}
- 以下同样会导致Crash,这是因为 i 会自动类型转换为无符号整数。
NSArray *array = @[@1, @2, @3, @4];
for (NSInteger i = array.count - 1; i >= (NSUInteger)0; --i) {
NSLog(@"%@", array[i]);
}
- 汇总如下
(lldb) p -1 > 0
(bool) $0 = false
(lldb) p -1 > (NSUInteger)0
(bool) $1 = true
(lldb) p (NSUInteger)-1 > (NSUInteger)0
(bool) $2 = true
实际开发中,上面的 0
和 array.count-1
往往会是变量名,具体值取决于外部赋值。这类的问题将会更加隐蔽,结果发到线上就是Crash工单,因此写代码中需要多多考虑。
2.2、可变数组多线程中,读取、写入同时操作
NSMutableArray *mutableArray = [NSMutableArray arrayWithArray:@[]];
for (int i=0; i< 666; i++) {
[mutableArray addObject:@(1)];
}
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSInteger totalCount = mutableArray.count;
for (NSInteger i = 0; i < totalCount; i++) {
NSLog(@"%@", mutableArray[i]);
}
});
dispatch_async(dispatch_get_global_queue(0, 0), ^{
for (NSInteger i = 0; i < 88; i++) {
[mutableArray removeObjectAtIndex:i];
}
});
这种类型属于多线程操作中没有做数据同步机制,实际开发中,新手也是常常犯的错误。对于复杂的多线程环境中,更加的隐蔽不易发现,很多的老手也会出现这样的问题。
网友评论