【问题标题】:Difference between '\0' and 0 for terminate the string'\0' 和 0 之间的区别用于终止字符串
【发布时间】:2018-02-01 18:35:28
【问题描述】:

我正在使用 JNI 代码生成随机字符串并使用以下代码将其返回给调用函数。

static const char alphanum[] =
        "abcdefghijklmnopqrstuvwxyz"; 

  jstring Utils::getRandomString(JNIEnv *env, const int len) {

        char s[len + 1];
        for (int i = 0; i < len; ++i) {
            int p = rand() % (sizeof(alphanum) - 1);
            s[i] = alphanum[p];
        }
        s[len] = 0;
        return env->NewStringUTF(s);
    }

我对如何在 JNI 中终止字符串感到困惑,我看到有两种方法

s[len] = 0;

s[len] = '\0'

谁能解释两者之间的区别?哪一个适合 JNI 代码?识别这个东西的原因是应用程序在添加 s[len] = '\0' 后在某些设备上崩溃,而它是 s[len] = 0; 它工作正常。 我无法生成此崩溃,但它已在结构控制台 http://crashes.to/s/2e4bca9a62c 上报告。

【问题讨论】:

  • 两者应该相同。 \0添加更多类型信息。
  • @Jarod42 根据我更新后的分析 s[len] = 0; to s[len] = '\0' 报告崩溃
  • “根据我在更新 s[len] = 0; 到 s[len] = '\0' 后报告崩溃的分析” 这似乎极不可能。您应该寻找其他可能性。
  • 既然这看起来是 C++,你为什么不用std::string?就此而言,您可能需要使用a better PRNG

标签: android c++ android-ndk java-native-interface


【解决方案1】:

您的问题和问题无关 - 让我回答您的问题... 您的崩溃是因为 NewStringUTF 没有复制它的参数;在 Java 字符串的生命周期内保持内存有效是您的责任。

但是,您提供了一个局部变量作为指针,它离开了范围;将对其的访问视为未定义的行为。

【讨论】:

  • @UKMoney 这里是崩溃报告crashes.to/s/2e4bca9a62c,can你请帮我解决这个问题
  • “您的崩溃是因为NewStringUTF 没有复制它的参数;您有责任在 java 字符串的生命周期内保持内存有效。” Java 字符串使用 UTF-16 编码,因此NewStringUTF 必然会将您提供的 UTF-8 数据转换为 UTF-16 并将其存储在一些新分配的内存中。只要NewStringUTF 返回,就可以释放保存原始 UTF-8 字符串的内存。
  • ART 在某些情况下可以进行字符串“压缩”,但不会触发转换。但它仍然复制字符串数据。
【解决方案2】:

谁能解释一下两者的区别?

在作业中:

s[len] = '\0';

'\0' 是一个char 文字常量

在作业中:

s[len] = 0;

0 是一个int 文字常量。由于这个int 被分配给char,它被转换chars 被声明为char s[len + 1])。该转换的结果与'\0' 具有相同的值。也就是说,在分配之后,评估条件:

s[len] == '\0'

结果为真。

在这种情况下,您使用哪一个并不重要,但我建议您坚持使用s[len] = '\0' 的形式,明确指出分配给char 的内容。

【讨论】:

  • 不是 0,当被视为 char 时,'\0'?
  • @isaac, int 0,当被视为 char 时,由于相应类型的实际大小,在大多数现代架构上相当 '\0\0\0\0'。但是与 char 的对话会减少更高的字节。它应该在编译时发生的当前上下文。
猜你喜欢
  • 2018-05-04
  • 2016-01-08
  • 2014-10-09
  • 2011-11-04
  • 1970-01-01
  • 1970-01-01
  • 2012-10-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多