我正在开发一个需要大量内存分配的android应用程序(很多图像缓冲区)。我正在使用Android NDK。我遇到了一些奇怪的崩溃。我希望这不会重复发布(经过以前的帖子后)
应用崩溃并出现以下错误:I / DEBUG(187):信号11(SIGSEGV),代码1(SEGV_MAPERR),故障地址00000004
我之前遇到了分段错误,并且已经解决了。
我很确定我正在正确分配和释放内存,因为我有相同的Windows设置,确认没有内存泄漏,我没有访问任何未分配的位置。 (没有derefrencing,没有坏指针)。在Windows上进行测试时未发现内存损坏。
我还确定分配和解除分配的JNI调用位于代码中的适当位置。仅在使用完成后才清除内存。
每次发生崩溃时,Backtrace都会显示不同的API调用,其中发生了错误。我已经记录了日志,没有一个指针是空的,它们是预期的。
此次崩溃非常随机。偶尔。 的一个即可。当我在应用程序内很长一段时间。 的 B'/ strong>即可。当应用程序内部执行大量操作时。但它大部分时间都很好用。
任何人都可以建议我的代码中的内存是如何被破坏的。可能导致这种情况的原因。
答案 0 :(得分:6)
检查您可能从结构或数组访问字段的位置。我这样说的原因是因为故障地址是00000004,这是一个NULL地址后的4个字节。检查每个字段访问,特别是在执行了很多次的代码中。 另外,检查malloc / new的NULL返回,您的设备可能内存不足。
由于您说当执行了大量操作或应用程序长时间运行时会出现此问题,因此我会检查内存泄漏。您的应用可能是消耗所有设备内存的应用。如果您有自定义分配器/解除分配器,您可能希望使用全局计数器,对于每次增加它的每个分配,对于每次释放,减少它。如果计数器太高,那就是记忆泄漏。
答案 1 :(得分:2)
崩溃的随机位置经常在堆栈损坏时发生,因此您应该仔细查看本地变量。例如,用M或类似的东西覆盖长度为N的数组。
答案 2 :(得分:1)
fault addr 00000004 =>意味着堆栈已损坏(非常接近0 addr)。
这是一个如何轻松复制此错误的示例,意外取消引用这样的字符串:
int a = foo();
LOGE("Foo() is %d", a ? "ok" : "not ok");
它应该是“%s”而不是“%d”
希望对某人有所帮助。