Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/225.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android上的共享库:结构值的字符串赋值(=)会导致segfault(dlfree) 我目前正在为C++设备开发一个C++共享库。_Android_C++_String - Fatal编程技术网

Android上的共享库:结构值的字符串赋值(=)会导致segfault(dlfree) 我目前正在为C++设备开发一个C++共享库。

Android上的共享库:结构值的字符串赋值(=)会导致segfault(dlfree) 我目前正在为C++设备开发一个C++共享库。,android,c++,string,Android,C++,String,在编写测试时,在示例代码中调用函数时,我遇到了导致segfault(dlfree)的奇怪行为 首先: 调用库函数的测试动态链接库 我还为linux和windows桌面编译了库和测试。在那里,它们运行时不会引起故障 静态链接时,segfault不会出现在android上 示例代码 typedef unsigned int DBRuleID; typedef std::string DBRuleTarget; struct DBRule { DBRuleID id; //int DBR

在编写测试时,在示例代码中调用函数时,我遇到了导致segfault(dlfree)的奇怪行为

首先:

  • 调用库函数的测试动态链接库
  • 我还为linux和windows桌面编译了库和测试。在那里,它们运行时不会引起故障
  • 静态链接时,segfault不会出现在android上
示例代码

typedef unsigned int DBRuleID;
typedef std::string DBRuleTarget;

struct DBRule {
  DBRuleID id; //int
  DBRuleTarget target; //std::string
};


//segfault variant
bool getRule(DBRuleID id, DBRule& rule) {
  rule.target = "I am causing segfault!";
  return true;
}


//working variant
bool getRule(DBRuleID id, DBRule& rule) {
  //nothing is set
  return true;
}
分段错误

Build fingerprint: 'generic/sdk/generic:3.0/HONEYCOMB/104254:eng/test-keys'
pid: 525, tid: 525  >>> /data/local/TestRulesDB <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr deadbaad
r0 deadbaad  r1 0000000c  r2 00000027  r3 00000000
 r4 00000080  r5 aff46658  r6 00013000  r7 00000004
 r8 00000004  r9 00013d3c  10 00000000  fp bec61a14
 ip ffffffff  sp bec61950  lr aff193e9  pc aff15f58  cpsr 00000030
         #00  pc 00015f58  /system/lib/libc.so
         #01  pc 00012d2a  /system/lib/libc.so (dlfree)
有人能给我解释一下吗?默认情况下初始化它的最佳方式是什么?

问题是

typedef unsigned int DBRuleID;
typedef std::string DBRuleTarget;

struct DBRule {
  DBRuleID id; //int
  DBRuleTarget target; //std::string
};


//segfault variant
bool getRule(DBRuleID id, DBRule& rule) {
  rule.target = "I am causing segfault!";
  return true;
}


//working variant
bool getRule(DBRuleID id, DBRule& rule) {
  //nothing is set
  return true;
}
  • 我做错了什么,我错过了什么
  • 是否有一种机制会多次尝试删除堆上已分配的内存
我已经在桌面上启动了valgrind,但是没有显示任何错误


提前谢谢

您的问题是所有空std::string对象的内部存储都使用相同的位置:任何空std::string的内部存储都是相同的静态成员。STL使用这个位置来确定是否应该释放std::string的内部存储

这适用于静态编译的代码,或者当您没有跨动态库边界传递空字符串时;但是当您处理动态库时,问题开始出现:可执行文件和每个动态库都将为空std::string提供不同的存储位置

下面是正在发生的事情:当代码执行时:

rule.target = "I am causing segfault!";
发生的第一件事是rule.target的内部存储被释放。如果rule.target是空的std::string(不管它是如何得到的),那么它将指向初始化代码的全局空std::string存储。如果这不是在库中发生的,那么库将断定它不是空字符串,并将尝试取消分配存储。但由于这是由客户机代码静态分配的,因此您会得到segfault


解决此问题的一种方法是静态链接库(如您所发现的);另一种方法是使用C++运行时的共享版本(并且要求客户端也这样做),它为空STD::string输出内部符号。最终的解决方案是避免直接或间接地在库的接口上使用std::string,如果有可能接收或发送空的std::string。

您的问题是所有空的std::string对象使用相同的位置作为其内部存储:任何空std::string的内部存储都是相同的静态成员。STL使用这个位置来确定是否应该释放std::string的内部存储

这适用于静态编译的代码,或者当您没有跨动态库边界传递空字符串时;但是当您处理动态库时,问题开始出现:可执行文件和每个动态库都将为空std::string提供不同的存储位置

下面是正在发生的事情:当代码执行时:

rule.target = "I am causing segfault!";
发生的第一件事是rule.target的内部存储被释放。如果rule.target是空的std::string(不管它是如何得到的),那么它将指向初始化代码的全局空std::string存储。如果这不是在库中发生的,那么库将断定它不是空字符串,并将尝试取消分配存储。但由于这是由客户机代码静态分配的,因此您会得到segfault


解决此问题的一种方法是静态链接库(如您所发现的);另一种方法是使用C++运行时的共享版本(并且要求客户端也这样做),它为空STD::string输出内部符号。最后的解决方案是,如果有可能接收或发送空的std::string,则避免直接或间接地在库的接口上使用std::string。

是否已分配内存来保存字符串值
strdup
ftw…我是否必须为结构中的类型字符串手动分配内存“额外”?你能给我举个简短的例子,让我更好地理解你的确切意思吗?谢谢请参阅strdup()和strdupa()都无法解决此问题。在尝试“写入”rule.target时,我会立即收到一个SEGFULT-无论如何。(.resize也失败)DBRuleTarget的结构声明是什么?这将有助于重新编辑您的问题以包含重要信息。您是否已分配内存来保存字符串值
strdup
ftw…我是否必须为结构中的类型字符串手动分配内存“额外”?你能给我举个简短的例子,让我更好地理解你的确切意思吗?谢谢请参阅strdup()和strdupa()都无法解决此问题。在尝试“写入”rule.target时,我会立即收到一个SEGFULT-无论如何。(.resize也失败)DBRuleTarget的结构声明是什么?这将有助于重新编辑您的问题,以包括这些重要信息。