【问题标题】:Fatal signal 11 (SIGSEGV), code 1 error when using Android NDK C++致命信号 11 (SIGSEGV),使用 Android NDK C++ 时出现代码 1 错误
【发布时间】: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&lt;calcArray-&gt;length();i++) 中,calcArray-&gt;length()calcArray 的第一个字符串元素的长度,而不是calcArray 本身的元素数量。尝试将 double calcExpression(string calcArray[]) 更改为采用 std::vector&lt;std::string&gt; 而不是 C 数组。
  • 您还可以在完成修改后在数组末尾插入一个特殊字符串。然后你可以像while calcArray[i] != "end" 这样遍历你的数组来知道长度
  • @Richard Critten 和 blackmesa,感谢您指出这些问题并提供建议!我修改了我的代码,以便在任何地方都可以访问数组大小,从而解决了我的问题。我之前在 doOperation 中也没有返回语句,当它是 double 类型时,但我意识到它应该是无效的,所以我也修复了该代码。我仍然收到相同的错误,但故障地址和 tid 不同。

标签: java android c++ android-ndk segmentation-fault


【解决方案1】:

我已经解决了我的问题,我的代码不再出现任何错误,我的应用也不再崩溃。实际上,代码的逻辑现在正在运行。有些功能仍然需要添加/更改,但这些与我这里提到的问题无关。

编辑:对我的代码的更改(可能)修复了它包括正确设置/获取 calcSum 中循环的最大值,使用双精度变量来存储双精度结果而不是 int(在 C++ 代码中的某个位置),并且可能还有其他变化。我意识到的另一件事是我的代码只是评估括号内的表达式,这不是程序的错,错误在于我对代码逻辑的假设。

总结:如果在这种情况下出现此错误,您可能需要修复您的代码,该程序在技术上按照您的代码运行。

【讨论】:

  • @rmtheis 我做了多项更改,很抱歉没有添加细节;我不记得所有细节,但我添加了我现在可以添加的内容。我还更新了帖子中的代码以反映我的更改/工作代码。
猜你喜欢
  • 1970-01-01
  • 2019-01-16
  • 2017-10-21
  • 1970-01-01
  • 1970-01-01
  • 2014-04-17
  • 1970-01-01
  • 1970-01-01
  • 2016-12-05
相关资源
最近更新 更多