程序运行问题排查和解决:an instance of ‘std::logic_error‘what(): basic_string::_M_construct null not valid

"博客讲述了在Java程序通过JNI调用C++接口时遇到的一个问题,即当传递空字符串("")作为jstring参数时,程序崩溃。问题源于在C++端对jstring转换为string时未正确处理空字符串的情况,导致内存异常。通过修改jni层的jstring2string函数,添加对空字符串的特殊处理,成功解决了该问题,使得程序能够正常运行。"

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

报错:

terminate called after throwing an instance of 'std::logic_error'what():  basic_string::_M_construct null not valid

        java程序调用jni接口运行服务,访问就会崩溃,idea报错如上,浏览器中则是无响应,且是跨域报错(这是服务停止无法请求导致的)。多次尝试后无果,逐一排查问题。

        检查java程序和接口,没有错误,然后排查jni层代码,注掉jni调用c++层的接口,发现仍然有问题,那么问题应该是出在jni层。再逐步排查发现是jstring参数解析过程出现的问题。

解决问题:

        由于需要,传入了jstring参数,参数可以为空可以有数据内容,参数在jni层解析转为string传入C代码,在C代码中判断处理。这里设计的参数为空传入形式可以是info=null;或者info=“”;为此在传入“”后出现了上述报错导致程序无法运行的情况。

jni层中使用的jstring2string函数为:

string jstring2string(JNIEnv *env, jstring jstr)//若jstr为“”时报错
{
	char* rtn = NULL;
	jclass clsstring = env->FindClass("java/lang/String");
	jstring strencode = env->NewStringUTF("GB2312");
	jmethodID mid = env->GetMethodID(clsstring, "getBytes", "(Ljava/lang/String;)[B");
	jbyteArray barr = (jbyteArray) env->CallObjectMethod(jstr, mid, strencode);
	jsize alen = env->GetArrayLength(barr);
	jbyte* ba = env->GetByteArrayElements(barr, JNI_FALSE);
	if(alen>0)
	{
		rtn = (char*)malloc(alen + 1);
		memcpy(rtn, ba, alen);
		rtn[alen] = 0;
	}
	env->ReleaseByteArrayElements(barr,ba,0);
	string stemp(rtn);
	free(rtn);
	return stemp;
}

        不难发现其中的原因:调用的jstring2string函数,传入空值"",alen=0,未处理却直接释放了相关内存,返回的也是坏内存,就会导致内存异常报错。

需要考虑到jstr=“”的情况,修改代码有:

string jstring2string(JNIEnv *env, jstring jstr)
{
	char* rtn = NULL;
	jclass clsstring = env->FindClass("java/lang/String");
	jstring strencode = env->NewStringUTF("GB2312");
	jmethodID mid = env->GetMethodID(clsstring, "getBytes", "(Ljava/lang/String;)[B");
	jbyteArray barr = (jbyteArray) env->CallObjectMethod(jstr, mid, strencode);
	jsize alen = env->GetArrayLength(barr);
	jbyte* ba = env->GetByteArrayElements(barr, JNI_FALSE);
	if(alen>0)
	{
		rtn = (char*)malloc(alen + 1);
		memcpy(rtn, ba, alen);
		rtn[alen] = 0;
	}
    else
    {
        env->ReleaseByteArrayElements(barr,ba,0);
        return "";
    }
	env->ReleaseByteArrayElements(barr,ba,0);
	string stemp(rtn);
	free(rtn);
	return stemp;
}

        修改后再运行程序测试就能够正常运行没有报错了,那么这个问题就解决了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

nanke_yh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值