每当我看到一个C"类"(通过访问将指针作为第一个参数的函数来使用的任何结构)时,我看到它们实现如下:
typedef struct
{
int member_a;
float member_b;
} CClass;
CClass* CClass_create();
void CClass_destroy(CClass *self);
void CClass_someFunction(CClass *self, ...);
...
Run Code Online (Sandbox Code Playgroud)
在这种情况下,它CClass_create始终malloc是内存并返回指向它的指针.
每当我看到newC++不必要地出现时,它似乎通常会让C++程序员疯狂,但这种做法在C中似乎是可以接受的.为什么堆分配的结构"类"如此常见?
我一直在努力深入了解编译器如何生成机器代码,更具体地说是GCC如何处理堆栈.在这样做的过程中,我一直在编写简单的C程序,将它们编译成汇编并尽力理解结果.这是一个简单的程序及其生成的输出:
asmtest.c:
void main() {
char buffer[5];
}
Run Code Online (Sandbox Code Playgroud)
asmtest.s:
pushl %ebp
movl %esp, %ebp
subl $24, %esp
leave
ret
Run Code Online (Sandbox Code Playgroud)
让我感到困惑的是为什么要为堆栈分配24个字节.我知道由于处理器如何寻址内存,堆栈必须以4为增量进行分配,但如果是这种情况,我们应该只将堆栈指针移动8个字节而不是24个.作为参考,缓冲区为17 bytes产生一个移动40个字节的堆栈指针,并且根本没有缓冲区移动堆栈指针8. 1到16个字节之间的缓冲区移动ESP24个字节.
现在假设8个字节是必要的常量(它需要什么?),这意味着我们分配16个字节的块.为什么编译器会以这种方式对齐?我正在使用x86_64处理器,但即使是64位字也只需要8字节对齐.为什么会出现差异?
作为参考,我正在使用gcc 4.0.1运行10.5的Mac上进行编译,并且未启用任何优化.
我试图比较堆栈和队列操作的增长率(运行时和空间),当实现为数组和链接列表时.到目前为止,我只能找到队列pop()的平均案例运行时间,但没有全面探索这两个数据结构并比较它们的运行时/空间行为.
具体地讲,我想找比较push()和pop()用于两个队列和堆栈,作为实现两个阵列和链表(因此2次操作×2种结构×2个实施方式中,或8个值).
另外,我会欣赏这两者的最佳,平均和最差情况值,以及与它们消耗的空间量有关的任何事情.
我能找到的最接近的是"所有cs作弊表的母亲"pdf,这显然是高级算法和离散函数的主人或博士级备忘单.
我只是在寻找一种方法来确定何时何地应该使用基于数组的实现与基于列表的堆栈和队列实现.
我想知道是否有一种方法可以使用2个堆栈在单个传递中解决中缀表达式?堆栈可以是一个用于操作员,另一个用于操作数...
通过分流码算法求解的标准方法是将中缀表达式转换为后缀(反向抛光)然后求解.我不想先将表达式转换为postfix.
如果表达式2*3-(6+5)+8如何,如何解决?
我多次被告知过这个问题.但我不知道为什么...从堆中分配内存时会涉及多少额外费用?它与硬件有关吗?它与CPU周期有关吗?如此多的猜测,但没有确切的答案......有人可以给我一些细节吗?
就像"放松"所说的那样,Heap数据结构比Stack更复杂.在我看来,一些内存空间在它开始运行时被分配给一个线程作为它的堆栈,而堆由进程内的所有线程共享.这种范例需要一些额外的机制来管理每个线程对共享堆的使用,例如垃圾收集.我对吗?
有关堆栈分配的许多相关问题是可以理解的
但是在各种*nix机器上,我可以发出bash命令
ulimit -s unlimited
Run Code Online (Sandbox Code Playgroud)
或者csh命令
set stacksize unlimited
Run Code Online (Sandbox Code Playgroud)
这如何改变程序的执行方式?是否对程序或系统性能有任何影响(例如,为什么这不是默认值)?
如果更多的系统细节是相关的,我主要关注在x86_64硬件上运行的Linux上使用GCC编译的程序.
多年来这个问题让我很困惑,考虑到这个网站的名字,这是值得一提的地方.
为什么我们程序员仍然有这个StackOverflow问题?
为什么在每个主要语言中线程堆栈内存都必须在创建线程时静态分配?
我将在C#/ Java的上下文中发言,因为我最常使用它们,但这可能是一个更广泛的问题.
固定堆栈大小会导致巨大的问题:
现在,如果堆栈动态调整大小,上面的所有问题都会大大减轻,因为堆栈溢出只有在存在内存溢出时才有可能.
但事实并非如此.为什么?现代CPU有一些基本限制会使其变得不可能/效率低下吗?如果你考虑重新分配所带来的性能ArrayList损失,它应该是可以接受的,因为人们一直使用结构而不会遭受太多痛苦.
所以,问题是,我错过了什么,StackOverflow不是问题,或者我错过了什么,有很多语言有动态堆栈,还是有一些很大的原因让这个不可能/难以实现?
编辑: 有人说性能会是个大问题,但请考虑一下:
可能重复:
堆栈和堆的内容和位置是什么?
关于ac程序中内存布局的基本概念,我理解:
有哪些方法可用于确定嵌入式/内存受限系统的最佳堆栈大小?如果它太大那么浪费的内存可以在其他地方使用.但是,如果它太小,那么我们得到这个网站的同名......
为了尝试快速启动:Jack Ganssle在"嵌入式系统设计的艺术"中指出,"凭借经验,人们可以学习标准的,科学的方法来计算堆栈的正确尺寸:随机选择尺寸并希望." 任何人都可以做得更好吗?
要求提供更具体的例子.那么,在没有操作系统的情况下使用IAR Embedded Workbench工具链,针对具有2 kB RAM 的MSP430 MCU的C程序怎么样?使用JTAG调试器时,此IDE可以显示堆栈内容和使用情况.
enter和之间的区别是什么?
push ebp
mov ebp, esp
sub esp, imm
Run Code Online (Sandbox Code Playgroud)
说明?是否存在性能差异?如果是这样,哪个更快,为什么编译器总是使用后者呢?
以相若方式将leave和
mov esp, ebp
pop ebp
Run Code Online (Sandbox Code Playgroud)
说明.