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

     首先看一段代码:

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语言基础,还要了解程序数据在内存中的布局情况,否则一不留神轻则程序出错,重则系统崩溃!

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值