【发布时间】:2016-05-03 08:22:30
【问题描述】:
通过 NDK 制作同时使用 Java 和 C++ 代码的 Android 应用程序时,我遇到了以下错误。具体来说,我尝试了许多有效的输入(这是一个计算器应用程序),它们都导致了这个错误,但是,例如,我尝试的一个是 4+3-5
05-03 00:54:05.676 30652-30652/com.x10host.dhanushpatel.nativecalc A/libc: Fatal signal 11 (SIGSEGV), code 1, fault addr 0xd89f95b0 in tid 30652 (atel.nativecalc)
05-03 00:54:06.462 30652-30652/com.x10host.dhanushpatel.nativecalc W/atel.nativecalc: type=1701 audit(0.0:1454): auid=4294967295 uid=10192 gid=10192 ses=4294967295 subj=u:r:untrusted_app:s0 reason="memory violation" sig=11
我不确定我的错误是什么或在哪里,或者如何解决它。
这是我的 C++ 代码:
#include <jni.h>
#include <stack>
#include <string>
#include <cctype>
#include <sstream>
#include <stdlib.h>
#include <android/log.h>
using namespace std;
stack<string> operationsStack;
stack<double> numbersStack;
int arraySize = 0;
extern "C" {
void doOperation() {
string oString = operationsStack.top();
operationsStack.pop();
double a = numbersStack.top();
numbersStack.pop();
double b = numbersStack.top();
numbersStack.pop();
if (oString == "x") {
numbersStack.push(a * b);
}
else if (oString == "/") {
numbersStack.push(b/a);
}
else if (oString == "+") {
numbersStack.push(a + b);
}
else {
numbersStack.push(b-a);
}
}
double calcExpression(string calcArray[]) {
for (int i = 0; i < arraySize; i++) {
string chr = calcArray[i];
if (chr == "(") {
}
else if (chr == "+" || chr == "x" || chr == "-" || chr == "/") {
operationsStack.push(chr);
}
else if (chr == ")") {
doOperation();
}
else {
numbersStack.push(atof(chr.c_str()));
}
}
doOperation();
double result = numbersStack.top();
numbersStack.pop();
return result;
}
JNIEXPORT jstring JNICALL
Java_com_x10host_dhanushpatel_nativecalc_MainActivity_calcPrint
(JNIEnv *env, jobject jot, jobjectArray calcArray, jint aSize) {
arraySize = aSize;
string cppArray[arraySize];
for (int i = 0; i < arraySize; i++) {
jstring string = (jstring) ((env)->GetObjectArrayElement(calcArray, i));
const char *rawString = env->GetStringUTFChars(string, 0);
cppArray[i] = rawString;
}
ostringstream oss;
oss << calcExpression(cppArray);
return env->NewStringUTF(oss.str().c_str());
}
JNIEXPORT void JNICALL
Java_com_x10host_dhanushpatel_nativecalc_MainActivity_calcCClear(JNIEnv *env) {
while (!operationsStack.empty()) {
operationsStack.pop();
}
while (!numbersStack.empty()) {
numbersStack.pop();
}
}
}
这是我的 Java 代码:
package com.x10host.dhanushpatel.nativecalc;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
private native String calcPrint(String[] jCL,int alLength);
private native void calcCClear();
ArrayList<String> jCalcList = new ArrayList<>();
TextView calcShow;
static {
System.loadLibrary("cplusplus11");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
calcShow = (TextView) findViewById(R.id.calcShow);
}
public void calcAdd(View v) {
Button b = (Button) v;
String buttonText = b.getText().toString();
Log.i("button pressed: ",buttonText);
jCalcList.add(buttonText);
calcShow.setText(calcShow.getText().toString()+buttonText);
}
public void calcSum(View v){
int jclSize = jCalcList.size();
String[] jCalcArray = new String[jclSize];
for(int i =0;i<jclSize;i++){
jCalcArray[i]=jCalcList.get(i);
}
calcShow.setText(calcPrint(jCalcArray,jCalcArray.length));
}
public void calcClear(View v){
calcCClear();
calcShow.setText("");
}
}
非常感谢您的帮助。提前致谢!
【问题讨论】:
-
在
for(int i=0;i<calcArray->length();i++)中,calcArray->length()是calcArray的第一个字符串元素的长度,而不是calcArray本身的元素数量。尝试将double calcExpression(string calcArray[])更改为采用std::vector<std::string>而不是 C 数组。 -
您还可以在完成修改后在数组末尾插入一个特殊字符串。然后你可以像
while calcArray[i] != "end"这样遍历你的数组来知道长度 -
@Richard Critten 和 blackmesa,感谢您指出这些问题并提供建议!我修改了我的代码,以便在任何地方都可以访问数组大小,从而解决了我的问题。我之前在 doOperation 中也没有返回语句,当它是 double 类型时,但我意识到它应该是无效的,所以我也修复了该代码。我仍然收到相同的错误,但故障地址和 tid 不同。
标签: java android c++ android-ndk segmentation-fault