Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/23.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
Objective c alloca对数组分配的偏好性与简单[]数组声明_Objective C_C_Macos_Memory Management - Fatal编程技术网

Objective c alloca对数组分配的偏好性与简单[]数组声明

Objective c alloca对数组分配的偏好性与简单[]数组声明,objective-c,c,macos,memory-management,Objective C,C,Macos,Memory Management,在阅读一些苹果代码时,我偶然发现了以下C代码块 allocasizeofCMTimeRange*3 这与通过内存分配堆栈相同吗 CMTimeRange*p=CMTimeRange[3] 对绩效有什么影响吗?是否需要释放内存?假设正如Joachim指出的,您的意思是CMTimeRange someVariableName[3] 两者都将在堆栈上分配内存 我猜alloca必须在函数序言之后添加额外的代码来进行分配。。。函数序言是编译器自动生成的代码,用于在堆栈上创建空间。结果是,一旦编译,您的函数可

在阅读一些苹果代码时,我偶然发现了以下C代码块

allocasizeofCMTimeRange*3

这与通过内存分配堆栈相同吗

CMTimeRange*p=CMTimeRange[3]


对绩效有什么影响吗?是否需要释放内存?

假设正如Joachim指出的,您的意思是CMTimeRange someVariableName[3]

两者都将在堆栈上分配内存

我猜alloca必须在函数序言之后添加额外的代码来进行分配。。。函数序言是编译器自动生成的代码,用于在堆栈上创建空间。结果是,一旦编译,您的函数可能会稍微大一点,但不会大很多。。。修改堆栈指针和堆栈框架的一些额外说明。我想如果调用不在条件分支中,编译器可以优化它,或者甚至可以将它提升到条件分支之外

我在我的MQX编译器上进行了实验,没有进行任何优化。。。这不是objective-c,只是c,也是一个不同的平台,但希望这是一个足够好的近似值,并且确实显示了所发出代码的差异。我使用了两个简单的函数,在堆栈上有一个大数组,以确保必须使用堆栈空间,因为变量不能单独存在于寄存器中

显然,在堆栈上放置大型数组是不可取的。。。这只是为了演示的目的

生成了以下汇编程序:

测试1: 数组a1和a2都放在函数序言中的堆栈上

   0: 1cfcb6c8                 push %fp
   4: 230a3700                 mov  %fp,%sp
   8: 24993901                 sub3 %sp,%sp,100    # Both arrays put on stack
   c: 7108                     mov_s    %r1,%r0
   e: 1b38bf98 0000dead        st   0xdead,[%fp,0xffff_fce0]        ; 0xdead
  16: e00a                     add_s    %r0,%r0,10
  18: 1b9cb018                 st   %r0,[%fp,0xffff_fe70]
  1c: 240a36c0                 mov  %sp,%fp
  20: 1404341b                 pop  %fp
  24: 7ee0                     j_s  [%blink]
测试2: 在程序中,只有数组a1放在堆栈上。。。必须生成额外的代码行来处理alloca

此外,除非有聪明的编译器对此进行优化,否则alloca内存将通过指针访问。。。我不知道这会导致实际的内存访问。自动变量可能会被优化为只是寄存器访问,这是更好的。。。编译器可以使用寄存器着色来确定哪些自动变量最好留在寄存器中,以及它们是否需要在堆栈上


我快速搜索了C99标准C11是关于。。。我的推荐信有点过时了。无法看到对alloca的引用,因此可能不是标准定义的函数。一个可能的缺点?

如果你真的只想在堆栈上分配3个元素,那么alloca的使用毫无意义。只有在运行时具有依赖于某个动态参数的可变长度,或者在同一函数中执行未知数量的此类分配时,才有意义

alloca不是一个标准函数,不同平台的函数不同。C标准更倾向于引入可变长度阵列(VLA)作为替代

这和通过…分配堆栈内存是一样的吗

我想不太可能。声明局部变量会导致在输入堆栈帧时保留内存,方法是从堆栈指针中减去变量的大小并调整对齐

它看起来可以通过在遇到堆栈指针时调整堆栈指针来工作。请注意手册页的Bugs部分

alloca依赖于机器和编译器;不鼓励使用它

alloca有点不安全,因为它无法确保指针返回指向有效且可用的内存块。所做的分配可能会超出堆栈的边界,甚至会深入内存中的其他对象,alloca无法确定此类错误。避免使用大量无限制分配的alloca

在我看来,这两点加起来就是:


不要使用ALLOCA

我想你的意思是CMTimeRange someVariableName[3]?你能提供一点关于这个调用的代码吗?与动态数组版本相比,ALLOCA为什么需要额外的代码?如果你的函数序言将所有自动变量的SP降低了5,那么,假设编译器没有优化,alloca必须生成另一个SP-=大小。这是一小段额外的代码,但OP要求区别。我不确定我是否理解。大概编译器必须改变堆栈框架以适应动态数组,所以我假设代码非常相似。。。事实上,我很傻,认为两者都是。。。但假设至少还有一个自动变量,我认为这一点仍然成立。假设我有4字节的自动变量。开场白对帧中的其他位和BOB执行SP-=4+x,x。然后说alloca4字节,必须生成另一个语句来执行第二个SP-=4。现在,编译器可能可以看到alloca。。。调用并仅发出一个SP-=8,但可能不会。再一次,我意识到这是一个微不足道的区别。。。这有意义吗?嗨,Jens,小注:C11将VLA减少为可选。仅在中需要C99@Jimbo,唯一一个没有实现VLA的大玩家是MS,我在那里
看不到他们的C11编译器。所有其他人的编译器中都有它,他们不会删除该功能。好的,很高兴知道,谢谢。上次我提到弗拉斯时,有人向我指出了这一点。看起来务实的答案是支持VLAs,尽管将来可能会下降,但我想如果供应商已经如您所说实施了VLAs,那么这是未知的或不太可能的
   0: 1cfcb6c8                 push %fp
   4: 230a3700                 mov  %fp,%sp
   8: 24993901                 sub3 %sp,%sp,100    # Both arrays put on stack
   c: 7108                     mov_s    %r1,%r0
   e: 1b38bf98 0000dead        st   0xdead,[%fp,0xffff_fce0]        ; 0xdead
  16: e00a                     add_s    %r0,%r0,10
  18: 1b9cb018                 st   %r0,[%fp,0xffff_fe70]
  1c: 240a36c0                 mov  %sp,%fp
  20: 1404341b                 pop  %fp
  24: 7ee0                     j_s  [%blink]
   0: 1cfcb6c8                 push %fp
   4: 230a3700                 mov  %fp,%sp
   8: 24593c9c                 sub3 %sp,%sp,50 # Only one array put on stack
   c: 240a07c0                 mov  %r4,%blink
  10: 220a0000                 mov  %r2,%r0
  14: 218a0406                 mov  %r1,0x190       # Extra for alloca()
  18: 2402305c                 sub  %sp,%sp,%r1     # Extra for alloca()
  1c: 08020000r                bl   _stkchk         # Extra for alloca()
  20: 738b                     mov_s    %r3,%sp # Extra, r3 to access write via pointer
  22: 1b9cbf98 0000dead        st   0xdead,[%fp,0xffff_fe70]        ; 0xdead
  2a: 22400280                 add  %r0,%r2,10
  2e: a300                     st_s %r0,[%r3] # r3 to access write via pointer
  30: 270a3100                 mov  %blink,%r4
  34: 240a36c0                 mov  %sp,%fp
  38: 1404341b                 pop  %fp
  3c: 7ee0                     j_s  [%blink]