- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我正在使用 C++ 构建一个 iOS 应用程序,遇到了一个大数组问题。问题是,如果数组达到一定大小,我将得到一个类型为 EXC_BAD_ACCESS (SIGSEGV) 的异常,子类型为 KERN_PROTECTION_FAILURE,带有段错误 (11) 终止信号。
有趣的是,无论我将数组放在堆栈上还是堆上,我都会收到该异常。
将数组放入堆栈的代码如下所示:
class Model
{
public:
Model() { };
private:
static constexpr std::size_t VERTEX_COUNT = 25894;
Vertex _vertices[VERTEX_COUNT] =
{
{ { 46.629387f, 647.478271f, 58.987785f }, { 0.140482f, 0.716024f, 0.683795f }, false },
{ { 86.409439f, 639.203247f, 57.095085f }, { 0.273239f, 0.689217f, 0.671059f }, false },
{ { 94.825722f, 586.618164f, 91.772812f }, { 0.375726f, 0.404750f, 0.833671f }, false },
{ { 50.570183f, 586.068481f, 100.536209f }, { -0.003906f, 0.451161f, 0.892434f }, false },
// 25894 array entries in total
};
// all the rest
}
用于填充数组的结构如下所示:
struct Vertex
{
Vertex()
{
}
Vertex(glm::vec3 coords, glm::vec3 norm, bool selected) :
coordinates(coords),
normal(norm),
isSelected(selected)
{
}
glm::vec3 coordinates;
glm::vec3 normal;
bool isSelected;
};
一旦模型实例被实例化,上述代码就会在 iOS 11.4 上崩溃。
现在,即使我换行也会发生这种情况
Vertex _vertices[VERTEX_COUNT] =
到(在堆上分配内存)
Vertex* _vertices = new Vertex[VERTEX_COUNT]
或到
std::unique_ptr<Vertex[]> _vertices = std::unique_ptr<Vertex[]>(new Vertex[VERTEX_COUNT]
或者将整个数组定义移动到 Model
的构造函数中。
到目前为止,我唯一能让它工作的方法就是改变
Vertex _vertices[VERTEX_COUNT] =
到
static constexpr Vertex _vertices[VERTEX_COUNT] =
并将相应的 constexpr 构造函数添加到 Vertex
结构。但是,我需要能够在运行时编辑数组,因此不能将其声明为 static constexpr
。
有没有人知道这里可能发生了什么?
最佳答案
您应该通过 new
创建数组,而无需初始化其元素。当您通过初始化在堆上创建数组时,编译器需要在堆栈上准备足够的空间来为数组的多个对象调用构造函数。
看下面的例子(它说明创建带初始化的动态数组是危险的):
struct vertex {
float x,y,z;
vertex() {}
vertex(double x,double y,double z){}
};
int main() {
vertex* v = new vertex[3] {
{1.43,2,3},
{3,4.34,5},
{3,4,5}
};
}
// main function in assembler code
push rbp
mov rbp, rsp
sub rsp, 48 // <--- stack pointer is decresed
mov eax, 36
mov edi, eax
call operator new[](unsigned long)
mov rdi, rax
// call ctors for vertex
asm 代码中最重要的一行是 sub rsp,48
。现在我们将数组的大小更改为有 6 个顶点:
vertex* v = new vertex[6] {
{1.43,2,3},
// 4 lines here
{3,4,5}
现在编译器生成 sub rsp, 80
,如您所见,从堆栈指针中减去的值增加了。
顶点数组越大,从堆栈中占用的空间就越多。堆栈是有限的。这可能就是为什么即使您将数组分配到堆上,您的应用程序也会崩溃。堆栈的所有内存都用于初始化数组的顶点。
我在 https://godbolt.org/ 上编译了这段代码选择了 clang 6.0,没有任何优化。 (启用的优化在输出 asm 代码中发生了很大变化)。当然,其他编译器可能会生成不同的代码,而不是 sub rsp,BIG_VALUE
它们可以分别为每个顶点的 ctor 分 block 占用堆栈空间。
关于c++ - 大型 C++ 数组导致 iOS 上出现段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53782233/
我的应用程序从一个有 5 个选项卡的选项卡栏 Controller 开始。一开始,第一个出现了它的名字,但其他四个没有名字,直到我点击它们。然后根据用户使用的语言显示名称。如何在选项卡栏出现之前设置选
我有嵌套数组 json 对象(第 1 层、第 2 层和第 3 层)。我的问题是数据表没有出现。任何相关的 CDN 均已导入。该表仅显示部分。我引用了很多网站,但都没有解决我的问题。 之前我使用标准表来
我正在尝试设置要显示的 Parse PFLoginViewController。这是我的一个 View Controller 的类。 import UIKit import Parse import
我遇到了这个问题,我绘制的对象没有出现在 GUI 中。我知道它正在被处理,因为数据被推送到日志文件。但是,图形没有出现。 这是我的一些代码: public static void main(Strin
我有一个树状图,其中包含出现这样的词...... TreeMap occurrence = new TreeMap (); 字符串 = 单词 整数 = 出现次数。 我如何获得最大出现次数 - 整数,
因此,我提示用户输入变量。如果变量小于 0 且大于 10。如果用户输入 10,我想要求用户再次输入数字。我问时间的时候输入4,它说你输入错误。但在第二次尝试时效果很好。例如:如果我输入 25,它会打印
我已经用 css overflow 属性做了一个例子。在这个例子中我遇到了一个溢出滚动的问题。滚动条出现了,但没有工作意味着每当将光标移动到滚动条时,在这个滚动条不活动的时间。我对此一无所知,所以请帮
我现在正在做一个元素。当您单击一个元素时,会出现以下信息,我想知道如何在您单击下一个元素而不重新单击同一元素时使其消失....例如,我的元素中有披萨,我想单击肉披萨看到浇头然后点击奶酪披萨看到浇头和肉
我有一个路由器模块,它将主题与正则表达式进行比较,并将出现的事件与一致的键掩码链接起来。 (它是一个简单的 url 路由过滤,如 symfony http://symfony.com/doc/curr
这个问题在这里已经有了答案: 9年前关闭。 Possible Duplicate: mysql_fetch_array() expects parameter 1 to be resource, bo
我在底部有一个带有工具栏的 View ,我正在使用 NavigationLink 导航到该 View 。但是当 View 出现时,工具栏显示得有点太低了。大约半秒钟后,它突然跳到位。它只会在应用程序启
我试图在我的应用程序上为背景音乐添加一个 AVAudioPlayer,我正在主屏幕上启动播放器,尝试在应用程序打开时开始播放但出现意外行为... 它播放并立即不断创建新玩家并播放这些玩家,因此同时播放
这是获取一个数字,获取其阶乘并将其加倍,但是由于基本情况,如果您输入 0,它会给出 2 作为答案,因此为了绕过它,我使用了 if 语句,但收到错误输入“if”时解析错误。如果你们能提供帮助,我真的很感
暂停期间抛出异常 android.os.DeadObjectException 在 android.os.BinderProxy.transactNative( native 方法) 在 androi
我已经为猜词游戏编写了一些代码。它从用户输入中读取字符并在单词中搜索该字符;根据字符是否在单词中,程序返回并控制一些变量。 代码如下: import java.util.Random; import
我是自动化领域的新手。这是我的简单 TestNG 登录代码,当我以 TestNG 身份运行该代码时,它会出现 java.lang.NullPointerException,双击它会突出显示我导航到 U
我是c#程序员,我习惯了c#的封装语法和其他东西。但是现在,由于某些原因,我应该用java写一些东西,我现在正在练习java一天!我要创建一个为我自己创建一个虚拟项目,以便让自己更熟悉 Java 的
我正在使用 Intellij,我的源类是 main.com.coding,我的资源文件是 main.com.testing。我将 spring.xml 文件放入资源文件中。 我的测试类位于 test.
我想要我的tests folder separate到我的应用程序代码。我的项目结构是这样的 myproject/ myproject/ myproject.py moduleon
这个问题已经有答案了: What is a NullPointerException, and how do I fix it? (12 个回答) 已关闭 6 年前。 因此,我尝试比较 2 个值,一个
我是一名优秀的程序员,十分优秀!