我是 C 和堆内存的新手,仍在努力理解动态内存分配。
我跟踪了Linux系统调用,发现如果我malloc用来请求少量的堆内存,那么内部malloc调用brk。
但是如果我使用malloc请求非常大量的堆内存,则在内部malloc调用mmap。
所以必须有一个很大的区别brk和mmap,但理论上我们应该能够使用brk分配堆内存无论请求的大小。那么为什么在分配大量内存时会malloc调用mmap呢?
我正在使用align-items和justify-content中心元素,我的HTML是:
<div class="flex-container">
<div class="item-1">div</div>
<div class="item-2">w=250px</div>
<div class="item-3">h=250px</div>
<div class="item-4">w/h=300px</div>
<div class="item-5">w=350px</div>
<div class="item-6">w=350px</div>
</div>
Run Code Online (Sandbox Code Playgroud)
我的css代码是这样的:
.flex-container {
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: center;
justify-content: center;
align-content: center;
}
Run Code Online (Sandbox Code Playgroud)
(我省略了一些不重要的CSS代码.)
所以结果会是这样的:
我不明白为什么两条线之间有这么大的空间(我知道使用align-content: center;可以解决,但我想知道那些多余的空间是如何在那里)
* {
box-sizing: border-box;
font-size: 1.5rem;
}
html {
background: #b3b3b3;
padding: 5px;
}
body {
background: #b3b3b3;
padding: 5px;
margin: 0;
}
.flex-container {
background: white;
padding: 10px;
border: 5px solid black;
height: 800px;
display: flex; …Run Code Online (Sandbox Code Playgroud)获取进程ID时pid_t数据类型和int之间有什么区别?我看到了类似的东西:
pid_t getpid(void);
Run Code Online (Sandbox Code Playgroud)
但它和有什么区别
int getpid(void);
Run Code Online (Sandbox Code Playgroud) 首先,我对movq和之间的区别有点困惑movabsq,我的教科书说:
常规movq指令只能具有可以表示为 32 位二进制补码的立即数源操作数。然后对该值进行符号扩展以生成目标的 64 位值。所述movabsq指令可以具有任意的64位立即值作为其源操作数,并且只能有一个寄存器作为目的地。
我有两个问题。
该movq指令只能具有可以表示为 32 位二进制补码的立即数源操作数。
所以这意味着我们不能做
movq $0x123456789abcdef, %rbp
Run Code Online (Sandbox Code Playgroud)
我们必须这样做:
movabsq $0x123456789abcdef, %rbp
Run Code Online (Sandbox Code Playgroud)
但是为什么movq被设计为不适用于 64 位立即数,这确实违背了q(四分字)的目的,我们需要movabsq为此目的而设置另一个,这不是很麻烦吗?
由于目标movabsq必须是寄存器,而不是内存,所以我们不能将 64 位立即数移动到内存中:
movabsq $0x123456789abcdef, (%rax)
Run Code Online (Sandbox Code Playgroud)
但有一个解决方法:
movabsq $0x123456789abcdef, %rbx
movq %rbx, (%rax) // the source operand is a register, not immediate constant, and the destination of movq can be memory
Run Code Online (Sandbox Code Playgroud)
那么为什么这条规则旨在让事情变得更难呢?
assembly x86-64 instruction-set cpu-architecture immediate-operand
我们有一个功能:
int caller()
{
int arg1 = 1;
int arg2 = 2
int a = test(&arg1, &arg2)
}
test(int *a, int *b)
{
...
}
Run Code Online (Sandbox Code Playgroud)
所以我不明白为什么&arg1和&arg2必须像这样被推到堆栈上
我可以理解我们可以通过使用获取被调用者中的arg1和arg2的地址
movl 8(%ebp), %edx
movl 12(%ebp), %ecx
Run Code Online (Sandbox Code Playgroud)
但是如果我们不把这两个推到堆栈上,我们也可以通过使用它们来解决它们的问题:
leal 8(%ebp), %edx
leal 12(%ebp), %ecx
Run Code Online (Sandbox Code Playgroud)
那么为什么要在堆栈上推送&arg1和&arg2呢?
假设我们有以下代码:
public IEnumerator FirstTest()
{
yield return 1;
}
public IEnumerable SecondTest()
{
yield return 1;
}
Run Code Online (Sandbox Code Playgroud)
我知道代码没有逻辑,但是它是有效的,那么“ yield”如何返回不同的类型,FirstTest返回IEnumerator,SecondTest返回IEnumerable?IEnumerator和IEnumerable之间没有继承关系
我们知道堆是一个零需求内存区域,它在未初始化的数据区域之后立即开始并向上增长(向更高的地址)。需求零是指CPU第一次接触堆区的虚拟页,对应的物理页全为零。
如果是这样,那么为什么有一个函数calloc用于将分配的内存初始化为零?如果访问时需求为零的页面已经为零,为什么需要再次将其初始化为零?
我对C中的动态链接库有一些疑问。
我的教科书使用图片说明DLL的工作方式,并且似乎复制了libvector.so和的一些重定位和符号表信息libc.so(箭头附在其侧面),但是每当汇编器遇到对最终位置未知的对象的引用时, ,它将生成一个重定位条目,告诉链接器将目标文件合并到可执行文件时如何修改引用。对于libc.so,一切都是已知的(具有所有定义),所以libc.so不应有任何重定位条目,不是吗?
Q2。我的教科书说:
“内存中共享库的.text部分的单个副本可以由不同的运行进程共享”,
假设我有一个使用的程序printf。是.text第printf一个程序结束时,驻留在RAM中的部分是永久保留还是从RAM中退出,而当第二个进程printf再次使用时,它会被加载到RAM中?如果是后者,那么由于我们有多个可以在后台运行的进程,将这.text部分printf移出并载入RAM的效率不是很高吗?
我们知道 .rel.text和.rel.data部分包含链接器需要重定位以生成最终可执行文件的重定位条目。
我的问题是,为什么要区分.rel.text和.rel.data分段?是不是更简洁,我们可以结合.rel.text和.rel.data部分成一个部分(例如.rel)?我们只需要在重定位条目 struct ( Elf64_Rela) 中添加一个位来指示重定位条目是与函数 ( .text) 还是全局变量 ( .data) 相关?
static void Main(string[] args) {
try {
var a = MyMethodAsync();
a.Wait(); // calling Wait throw an AggregateException
}
catch (Exception e) {
Console.WriteLine("Catch");
}
Console.ReadLine();
}
static async Task<String> MyMethodAsync() {
String s = await TestThrowException();
return s;
}
static Task<String> TestThrowException() {
return Task.Run(() => {
throw new DivideByZeroException();
return "placeholder"; // return statement is needed for the compilier to work correctly
});
}
Run Code Online (Sandbox Code Playgroud)
上面的代码有效, Main 方法中的 catch 块可以捕获AggregateException异常(源自TestThrowException并转换为AggregateException)。
但如果我有这样的代码:
static void …Run Code Online (Sandbox Code Playgroud)