问题标签 [alloca]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
122 浏览

c - alloca 代替 alsa 中的局部变量

我使用示例 C ALSA 程序作为参考,并运行以下代码:

基于 ALSA 源代码,snd_ctl_event_alloca是一个宏,调用__snd_allocawhich 是一个宏,最终扩展为以下等效行snd_ctl_event_alloca(&event);(经过一些简单的简化):

wheresnd_ctl_event_sizeof()在整个库中只实现一次,如下所示:

所以我的问题是,这整个过程不等同于简单地做:

作为参考,这些是宏:

说明:

  • 上面的第一个代码块位于函数体的开头,而不是嵌套块中

编辑

事实证明(据我了解),做:

给出一个storage size of 'event' isn't known错误,因为snd_ctl_event_t显然是一个私有定义的不透明结构。因此,唯一的选择是动态分配。

0 投票
3 回答
165 浏览

c++ - 如果抛出异常,alloca() 是否会返回内存?

我正在维护一个似乎内存泄漏缓慢的遗留 C++ 应用程序。我已经设法通过确保当前配置不再引发任何异常来“修复”内存泄漏,并且我还可以触发泄漏并通过将其配置为导致许多异常来扩展它。

所有分配的内存都是使用 alloca() 而不是 malloc() 完成的。我对此给出的解释是,这是因为 alloca() 的工作方式类似于 java 垃圾收集器,并且在退出上下文时会自动释放内存。

由于泄漏是如此明显地与抛出的异常绑定,我有理论认为 alloca() 在抛出异常时无法释放内存。

这完全合理吗?如果是真的,我觉得它是 alloca() 的一个主要缺陷,但是当我用谷歌搜索 alloca() 时,它似乎通常是一个问题。

我会很感激任何专家的见解。

0 投票
3 回答
447 浏览

c - 构造一个指向 alloca 的函数指针会导致链接器错误?

我正在尝试编写一个函数,该函数传递一个用于分配的函数作为其参数;它应该接受任何类型的有效分配器void *(*)(size_t)。但是,在尝试用作分配器时,我遇到了奇怪的行为alloca-构造指向函数的函数指针可以alloca正常编译,但会导致链接器错误:

结果是

这是否与 alloca 内联有关?但是当函数不需要地址时,内联不会仅作为优化来完成。事实上,使用 GCC,我什至可以编写自己的版本,在上面的代码中按预期工作:

标准版本的行为方式不同是否有原因?

0 投票
2 回答
62 浏览

c - 在堆栈上声明内存会覆盖之前声明的内存

如何在堆栈上分配内存并让它指向不同的内存地址以便我以后可以使用它?例如。这段代码:

每次都会打印出相同的地址。如何将内存写入堆栈(不是堆,没有 malloc),并且不会覆盖堆栈上的其他内容。

0 投票
2 回答
592 浏览

c - Can alloca() memory be reallocated?

Memory allocated by malloc can be reallocated with realloc. Is there a similar function for alloca? Reallocating stack memory could be useful when you don't want memory to be allocated on the heap, and you need to allocate variable stack memory multiple times, for example in a library function, where you need dynamic memory, but don't want to allocate on the heap, because the user of the library might use a custom heap allocation strategy. It would look like this:

The important thing is that this all happens on the stack. Q: is there a way to reallocate dynamic stack memory?

0 投票
1 回答
201 浏览

optimization - 如何告诉 LLVM 它可以优化离店?

背景(可能有更好的方法来做到这一点):我正在开发一个手动管理内存的 Julia 库;我mmap是一个大块,然后主要将其视为堆栈:函数接收指针作为参数,如果它们分配一个对象,它们将向被调用者返回一个递增的指针。该被调用者本身可能不会增加指针,并且只返回它收到的原始指针,如果它返回指针的话。

每当一个函数返回时,就我的库而言,指针当前位置之外的任何东西都是垃圾。我希望 LLVM 能够意识到这一点,以便它可以优化掉任何不必要的存储。

这是一个演示问题的测试用例:取两个长度为 16 的向量的点积。首先,一些初步加载(这些是我的库,在 GitHub 上:SIMDPiratesPaddedMatrices):

当然,如果我们手工编写点积,我们永远不会包括商店,但是当您尝试为任意模型生成代码时,这要困难得多。所以我们将编写一个坏点积存储到一个指针中:

我们不是循环一次并用fma指令累积点积,而是循环两次,首先计算和存储产品,然后求和。我想要的是让编译器找出正确的东西。

这里有两个版本在下面调用它。第一个使用 llvm生命周期内在函数尝试将指针内容声明为垃圾:

第二个不是使用预分配的指针,而是使用alloca创建一个指针

两者当然都得到正确答案

但只有 alloca 版本被正确优化。alloca 的程序集(AT&T 语法):

如您所见,没有移动到内存中,我们有 1vmul和 3 vfmadds 来计算点积(在进行向量缩减之前)。

不幸的是,这不是我们从尝试使用生命周期的版本中得到的:

在这里,我们只得到写好的循环:vmul,存储到内存中,然后vadd. 然而,4 个中的一个已被替换为fmadd.

此外,它不会从任何商店读取,所以我认为死店消除通行证应该没有问题。

相关的 llvm:

它省略了allocastores。但是,尝试使用生命周期:

生命周期的开始和生命的结束都在那里,但四家商店中的三家也是如此。我可以确认第四家商店不见了:

在没有指定生命周期的情况下,所有四个当然都必须发生:

然而,与 不同的是alloca,它无法忽略所有 4 家商店。

作为参考,我使用 LLVM 8.0.1 构建了 Julia。

我没有使用堆栈指针来代替我的堆栈指针有两个原因:a) 在使用-created 指针alloca调用非内联函数时出现错误。alloca用其他指针替换这些指针会使错误消失,内联函数也是如此。如果有办法解决这个问题,我至少可以alloca在更多地方使用。b) 我不知道如何让 Julia 每个线程有超过 4MB 的堆栈可供 alloca 使用。我认为 4MB 对于我的许多用例来说已经足够了,但不是全部。如果我的目标是编写相当通用的软件,那么这样的限制并不是很好。

我的问题:

  • 有什么方法可以让 LLVM 复制它在 alloca 中显示的行为?
  • 我是否正确地做事,并允许 LLVM 显示所需的行为,但由于某种原因,优化器比alloca?
  • 因此可以预期在未来的版本中会有所改进。
  • 关于如何处理这个问题、更好地启用优化器或我一般缺少的东西的任何建议?
  • 鉴于只有最后一个被省略,问题是它假设它们可能有别名吗?
0 投票
1 回答
65 浏览

c++ - 使用赋值运算符检查和对齐 alloca() 的临时生命周期

在编写大型代码库的一些测试和分析过程中,我不得不用自己的方法替换对 alloca() 的数千次调用。在我的目标平台上,如果数字为零,alloca() 将失败,因此我们要断言是这种情况。我们还希望提供一个单一调用的对齐版本。但是, alloca() 具有与范围相关的特定生命周期,所以虽然我想写

显然,这不是一个选项,因为 alloca() 不会超过 CheckAndAllocate()。

在解决这个问题的过程中,我使用临时写了这个替代方案:

此外,我还将对齐版本定义为:

我的问题是 - 鉴于 alloca 返回的值是通过临时的,这是否因为任何类型的作用域而违反了 alloca 的分配?

我认识到 alloca 存在缺陷,并且有多种解决方案可以解决此问题,但我希望将这些更改注入代码库而不更改任何其他内容,而只是添加一些诊断。

我也只是对这种特定模式感到好奇。

这是 MSVC2019、CLANG 和小众实时系统编译器。

0 投票
2 回答
111 浏览

c - Visual C 的 strdupa() 实现

我正在尝试将 C(不是 C++)程序从 GCC 移植到 Visual Studio。

GCC 特定的函数 strdupa() 在这个程序中被广泛使用。有没有办法为 Visual C 实现这个功能。

PS。我知道它使用 alloca() 并且不安全。但它现在在 GCC 上运行得很好,我认为在一个地方实现相同的功能然后改变程序的逻辑更安全。我也不希望性能下降。

0 投票
1 回答
95 浏览

assembly - 试图了解 x86 上 alloca() 函数的汇编实现

我对汇编很陌生,我目前正在阅读一本名为《逆向工程初学者》的书,我进入了讨论堆栈内存分配的部分。我理解(我认为)堆栈分配的概念,但在示例中有些东西我不理解,如果有人能提供帮助,我会很高兴。

书中以这个函数为例:

我了解 C 函数的作用。它在堆栈上分配 600 字节的内存,然后将字符串“hi!”写入该空间。使用该_snprintf 功能。然后函数打印它。

目前一切都很好。之后,本书给出了 MSVC 编译器生成的汇编实现,代码如下所示:

在这里,我知道EAX寄存器将包含__alloca_probe_16函数的参数。但现在有些东西对我来说没有意义。据我了解,该函数基本上只是减去from__alloca_probe_16值中的字节数。EAXESP

例如,如果ESP指向 1000 现在它指向 400。然后我们将 400 存储到ESI并开始将参数压_snprintf入堆栈,并ESI指向函数需要开始写入数据的位置。所以我的问题是,如果ESPESI寄存器都指向 400 并且我从 1000-400(600 字节)分配内存,并且我开始将东西压入堆栈,它们不会进入从 400 开始的位置并减少? 我的意思是,如果不使用它们,为什么要减去 600 字节?在我看来,这就是堆栈在行后的样子push esi

我知道我可能错了并且没有理解正确的东西,因为我认为这本书没有错,如果有人能帮助我理解这段汇编代码中发生的事情,我会很高兴。

0 投票
1 回答
66 浏览

c - 有没有办法在 GNU C 中显式操作堆栈上的变量数据?

(GNU) C 提供了至少两种在堆栈上操作可变数据的机制——第一种是alloca函数及其相关项(例如strdupa),第二种是“可变长度数组”功能。

问题alloca在于它似乎没有在内存中分配连续区域 - 程序

印刷

这表明后续分配可能会返回四倍的单词(但我希望它是特定于实现的——我只在基于 ARM 的手机上尝试过这段代码)。

是否有任何“认可”的方式将单个值推入堆栈,而不是使用预先已知的大小分配它们?

我的意思是:

我正在寻找一种适用于 x86 和 ARM 的解决方案。(我认为研究这些平台的 ABI 并编写可以扩展为显式操作堆栈指针的程序集的宏是一种选择,但我没有时间自己探索这个)