所以,我需要一些帮助.我正在用C++开发一个项目.但是,我想我已经设法破坏了我的堆.这是基于我std::string向一个类添加了一个并从另一个类中赋值的事实std::string:
std::string hello = "Hello, world.\n";
/* exampleString = "Hello, world.\n" would work fine. */
exampleString = hello;
Run Code Online (Sandbox Code Playgroud)
使用堆栈转储在我的系统上崩溃.所以基本上我需要停下来查看我的所有代码和内存管理内容,找出我搞砸了的地方.代码库仍然很小(约1000行),因此这很容易实现.
不过,我对这种东西感到头疼,所以我想我会把它扔出去.我在一个Linux系统上并且已经四处乱窜valgrind,虽然我不知道我在做什么,但它确实报告说它std::string的析构函数是无效的.我不得不承认从谷歌搜索中获得"堆腐败"一词; 关于这类东西的任何通用文章也将受到赞赏.
(之前rm -rf ProjectDir,在C#再做一次:D)
编辑:我还没有说清楚,但我要求的是诊断这些记忆问题的建议.我知道std :: string的内容是正确的,所以这是我做过的事情(或者是一个bug,但是选择不是问题).我确信我可以查看我编写的代码,你很聪明的人会立即看到问题,但我想将这种代码分析添加到我的'工具箱'中,就像它一样.
在C++中,堆栈可能以哪种方式被破坏.我猜测的一种方法是通过访问超出其边界的数组来覆盖堆栈变量.有没有其他方式可以被破坏?
我一直在研究编程语言是如何工作的,其中一些有一个所谓的虚拟机.我知道这是在另一种编程语言中对编程语言进行仿真的某种形式,并且它的工作方式与使用堆栈执行编译语言的方式相同.我做对了吗?
根据我所做的附带条件,让我感到困惑的是,许多非编译语言允许使用"自由"类型系统的变量.以Python为例,我可以这样写:
x = "Hello world!"
x = 2**1000
Run Code Online (Sandbox Code Playgroud)
字符串和大整数是完全不相关的,并且在内存中占用不同的空间,那么这个代码如何在基于堆栈的环境中表示?这到底发生了什么?x是否指向堆栈中的新位置并且旧的字符串数据未被引用?这些语言不使用堆栈吗?如果没有,它们如何在内部表示变量?
我的代码中有很少的堆栈用于跟踪我的逻辑位置.在某些时候我需要复制堆栈,但我似乎无法以保留订单的方式克隆它们.我只需要浅层复制(引用,而不是对象).
这样做的正确方法是什么?或者我应该使用其他类型的堆栈?
注意:我看到这篇文章Stack Clone Problem:.NET Bug或Expected Behavior?,但不确定如何为Stack类设置克隆方法.
注意#2:我使用System.Collection.Generic.Stack
刚开始学习x64程序集,我对函数,参数和堆栈有疑问.据我所知,函数中的前四个参数传递给Windows中的rcx,rdx,r8和r9寄存器(以及浮点数的xmm0-xmm3).所以带有四个参数的简单加法函数如下所示:
add:
mov r10, rcx
add r10, rdx
add r10, r8
add r10, r9
mov rax, r10
ret
Run Code Online (Sandbox Code Playgroud)
但是,我遇到的文档提到了这一点:
每个函数至少必须在堆栈上保留32个字节(4个64位值).该空间允许将传递到函数中的寄存器轻松复制到众所周知的堆栈位置.不需要被调用函数将输入寄存器参数溢出到堆栈,但堆栈空间预留确保它可以在需要时使用.
所以,我必须预留堆栈空间,即使我做的功能需要四个参数或更低,或者是它只是一个建议?
编译C程序并创建目标文件(ELF)时.目标文件包含不同的部分,如bss,数据,文本和其他段.我知道ELF的这些部分是虚拟内存地址空间的一部分.我对吗?如果我错了,请纠正我.
此外,将存在与编译的程序相关联的虚拟存储器和页表.页表在加载程序时将ELF中存在的虚拟内存地址与实际物理内存地址相关联.我的理解是否正确?
我在创建的ELF文件中读到,bss部分只保留未初始化的全局变量的引用.这里未初始化的全局变量是指在声明期间未初始化的变量?
另外,我读到局部变量将在运行时(即堆栈中)分配空间.那么它们将如何在目标文件中引用?
如果在程序中,有特定的代码段可用于动态分配内存.如何在目标文件中引用这些变量?
我很困惑,目标文件的这些不同部分(如文本,rodata,数据,bss,堆栈和堆)是物理内存(RAM)的一部分,所有程序都在其中执行.但我觉得我的理解是错误的.当进程或程序执行时,这些不同的段如何与物理内存相关?
我前段时间和朋友讨论过.他是一位经验丰富的C++用户,我不是一位经验丰富的C++用户.他告诉我,我应该努力使用堆变量,即:
A* obj = new A("A");
Run Code Online (Sandbox Code Playgroud)
而不是:
A obj("A");
Run Code Online (Sandbox Code Playgroud)
除了使用指针很好和灵活的所有东西之外,他说最好把东西放在堆而不是堆栈中(关于堆栈的东西比堆小?).这是真的吗?如果是这样的话?
编辑:我写了一个错字,说我的朋友建议堆栈变量.他推荐堆变量.
Edit2:我知道有关生命的问题.让我们假设我已经适当地管理了这些变量的生命周期.(即关注的唯一标准是堆与堆栈存储,没有生命周期问题)
我保证之前已经问过这个问题,但是我无法通过搜索找到它; 对于任何裁员,提前抱歉.
这是我(可能错误的)理解,只有在编译时知道对象的大小时才分配给堆栈.因此,在初始化数组的情况下,您可以执行其中一个(这应该在堆栈上):
char charArray[50];
Run Code Online (Sandbox Code Playgroud)
由于此数组的大小在编译时是已知的,因此应该没有问题.
另一方面,这(我相信)也是有效的代码:
char anotherCharArray[someVariable + 50];
Run Code Online (Sandbox Code Playgroud)
这也会在堆栈上进行吗?我很确定代码段错误,如果你释放()这个,所以它让我觉得它确实如此,但它对我来说真的没有意义.同样,100%唯一的情况是,当通过malloc分配数据时,你必须使用free()?
在此先感谢您的帮助.
我正在尝试将自定义文本按钮添加到 AppBar 的前导属性中。但是,当文本太长时,就会变成多行。如何解决这个问题?