jni错误"@@@ ABORTING: INVALID HEAP ADDRESS IN dlfree"

来源:互联网 发布:葡萄游戏厅同类软件 编辑:程序博客网 时间:2024/04/28 14:19

     首先看一段代码:

typedef WORD unsigned short;JNIEXPORT jobject XXX_getString(JNIEnv* env, jobject thiz, jint file,jobject head,jobject word,jint index){jobject jstr = NULL;int i = 0,j,len;    WORD *buf;    int adr = (*env)->GetIntField(env,word,wd_ExplainAddress);    len = getWordStartAddress(file,index + 1,(*env)->GetIntField(env,head,dh_CodeAddressTable)) - adr;        buf = (WORD*)malloc(len + 2);    if(buf == NULL){        return NULL;    }    lseek(file,adr,SEEK_SET);    read(file,buf,len);    buf[len / 2 + 1] = 0;    while(buf[i]){        if((buf[i] >= 0xF800) &&(buf[i] <= 0xF8FF) || (buf[i] >= 0xF700) &&(buf[i] <= 0xF70D)){            j = i;            while(buf[j]){                buf[j] = buf[j + 1];                j++;            }            continue;        }        i++;    }    buf[i] = 0;    jstr = (*env)->NewString(env,buf,i);    free(buf);    return jstr;}
就是上面的一段代码,其中有一行有问题,导致了出现“@@@ ABORTING: INVALID HEAP ADDRESS IN dlfree”错误

通过错误提示,说明是内存出错了,而且是在free的时候出错的,即上面第33行。但是free怎么会出错呢,除非前面malloc的内存出错了,要么free是错误的地址,或者malloc的内存被访问越界了,粗看一下,buf的地址没变过,因此地址不会错,难道是越界?那究竟是怎么越界的呢?

buf 指针为WORD型,分配了(len+2)个字节,说明最小有2个字节,然后buf[len/2+1]=0,将分配的最后一个WORD置0,所以20行和23行的while语句也是不会越界的。那到底是哪里呢?你可能说len小于0的话就不行,因为这个len是计算出来的,所以逻辑上已经排除了。好,len也不会小于0,while循环也不会出界,那怎么还会出错呢?

仔细看一下,如果len是奇数呢,比如3,buf = malloc(3+2),buf有5个字节,第19行,buf[3/2+1] = buf[2] = 0,因为buf是WORD型的,每个元素2个字节,buf[2]就是buf开始后的第5、6个字节,因为分配的buf只有5个字节,现在要访问第6个字节,所以越界了。

测试中发现,第9行得到的len一直都是偶数,并不存在奇数的情况,可还是一样的错误,因此这个属于内存对齐的问题了。关于内存对齐,网上资料比较多,这里贴出一个网址以供参考:

内存对齐的规则以及作用

不好意思,上面加删除线的一段话其实是错误的,不知道有多少人看了这篇博客,误导了大家,实在对不起难过!这里其实不是对齐的问题,就是内存越界了,主要祸根就是第11行,这里本来是要申请一块连续的WORD(每个元素2个字节)型空间的,结果申请的是BYTE(每个元素1个字节)型空间,因为malloc是按字节数来分配的,所以尽管增加了2个字节的长度,在后面肯定是会内存出界的。上面的buf[2]应该是buf开始后的第4、5个字节,因此还没出界。现在用偶数代替,比如len=4,buf=malloc(4+2),buf有6个字节,第19行,buf[4/2+1]=buf[3]=0,因为buf是WORD型,buf[3]就是buf开始后的第6、7个字节,因为分配的buf只有6个字节,现在要访问第7个字节,所以越界了。由此可见,指针的使用必须要严格谨慎,必须要有扎实的C语言基础,还要了解程序数据在内存中的布局情况,否则一不留神轻则程序出错,重则系统崩溃!