在最近的项目开发中,由于需要使用C语言的算法供给OC项目调用,所以研究了一下OC与C的混编及.a库的相关生成。而在混编的过程中,C语言的算法都能正常调用了,但是被一个问题困扰了很长一段时间,就是在连续调用的过程中,很容易抛出野指针而导致程序崩溃,且Xcode无法捕捉相应的异常。下面是我的部分OC与C的混编代码:
NSString *strMsg = [[NSString alloc]initWithString:msg]; const char * a =[strMsg UTF8String]; int dataLen = (int)[[strMsg dataUsingEncoding:NSUTF8StringEncoding] length]; char *bufA = new char[dataLen]; bzero(bufA, sizeof(bufA)); strcpy(bufA, a); NSString *strKey = [[NSString alloc]initWithString:key]; NSInteger keyLen = [[strKey dataUsingEncoding:NSUTF8StringEncoding] length]; const char * b =[strKey UTF8String]; char *bufB = new char[keyLen]; bzero(bufB, sizeof(bufB)); strcpy(bufB, b); size_t bloklen = ((dataLen / 16) + (dataLen % 16 > 0 ? 1: 0)) * 16; a = nil; b = nil; char *bufC =(char *) malloc(bloklen); bzero(bufC, sizeof(bufC)); Encrypt(bufA, bufB, bufC, dataLen); bufA = nil; bufB = nil; free(bufC);
由于知道是因为开辟内存的时候才抛出的野指针,所以搜索了很多相关资料,最后才发现是由于使用了strcpy(char *,const char*)的方法的缘故。strcpy是C语言标准库的函数,它是把从src地址开始且含有'\0'结束符的字符串复制到以dest开始的地址空间,需要指定长度,且遇到被复制字符的串结束符"\0"才结束,所以容易溢出。所以我换成了另外一种复制函数void *memcpy(void *dest, const void *src, size_t n),就很好的解决了内存溢出的问题。
strcpy和memcpy主要有以下3方面的区别。
1、复制的内容不同。strcpy只能复制字符串,而memcpy可以复制任意内容,例如字符数组、整型、结构体、类等。
2、复制的方法不同。strcpy不需要指定长度,它遇到被复制字符的串结束符"\0"才结束,所以容易溢出。memcpy则是根据其第3个参数决定复制的长度。
3、用途不同。通常在复制字符串时用strcpy,而需要复制其他类型数据时则一般用memcpy。