我刚刚完成了一项测试,作为求职面试的一部分,一个问题让我感到难过 - 甚至使用谷歌作为参考.我想看看stackoverflow工作人员可以用它做什么:
"memset_16aligned"函数需要传递给它的16byte对齐指针,否则它将崩溃.
a)如何分配1024字节的内存,并将其与16字节边界对齐?
b)执行memset_16aligned后释放内存.
{
void *mem;
void *ptr;
// answer a) here
memset_16aligned(ptr, 0, 1024);
// answer b) here
}
Run Code Online (Sandbox Code Playgroud) 从以前的问题,在这个论坛上,我了解到,在大多数存储系统中,L1缓存L2缓存的子集,是指从L2删除任何条目也从L1删除.
所以现在我的问题是如何在L1缓存中为L2缓存中的条目确定相应的条目.存储在L2条目中的唯一信息是标签信息.根据此标记信息,如果我重新创建addr,如果L1和L2缓存的行大小不相同,它可能会跨越L1缓存中的多行.
该体系结构是否真的打扰了两条线路,或者它只是保持具有相同线路大小的L1和L2缓存.
我知道这是一个政策决定,但我想知道常用的技术.
说到C++的并发内存模型,Stroustrup的C++编程语言,第4版,第1节.41.2.1,说:
...(像大多数现代硬件一样)机器无法加载或存储任何小于单词的东西.
但是,我的x86处理器,几年前,可以存储小于一个字的对象.例如:
#include <iostream>
int main()
{
char a = 5;
char b = 25;
a = b;
std::cout << int(a) << "\n";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如果没有优化,GCC将其编译为:
[...]
movb $5, -1(%rbp) # a = 5, one byte
movb $25, -2(%rbp) # b = 25, one byte
movzbl -2(%rbp), %eax # load b, one byte, not extending the sign
movb %al, -1(%rbp) # a = b, one byte
[...]
Run Code Online (Sandbox Code Playgroud)
评论是由我提出的,但是汇编是由GCC提出的.当然,它运行良好.
显然,我不明白Stroustrup在谈到硬件可以加载和存储任何小于一个单词的内容时所说的内容.据我所知,我的计划什么也不做,但加载和存储对象小于一个字的.
C++对零成本,硬件友好的抽象的彻底关注使C++与其他易于掌握的编程语言区别开来.因此,如果Stroustrup在公交车上有一个有趣的信号心理模型,或者有其他类似的东西,那么我想了解Stroustrup的模型.
什么是 Stroustrup谈论,拜托?
更长时间的背景声明 …
据我所知,变量类型,例如之间的唯一差别char,int等等是记忆它们占据的量.我猜他们在调节他们所拥有的变量代表什么方面没有任何作用.如果这是真的,在这里,我看到以下内容strcmp:
strcmp函数将字符串s1与s2进行比较,返回一个与第一个不同字符对之间的差异具有相同符号的值(解释为unsigned char对象,然后提升为int).
我想问为什么结果会提升到int?由于chars被比较,它们的差异char在所有情况下都适合.因此,不推广结果int只是在结果的末尾附加一堆0?那么,为什么这样做呢?
C(和C++)包括一系列动态内存分配函数,其中大部分都是直观命名的,并且易于向程序员解释,并对内存有基本的了解.malloc()简单地分配内存,同时calloc()分配一些内存并急切地清除它.还有,realloc()并且free(),这是非常不言自明的.
malloc()也提到的联机帮助页valloc(),它分配与页边框对齐的(size)字节.
不幸的是,我的背景在低级错综复杂方面不够彻底; 分配和使用页面边界对齐的内存有什么影响,什么时候这是适当的,而不是常规malloc()或calloc()?
我试图理解为什么只包含 int 的结构在类中占用 8 个字节的内存。
考虑以下代码;
static void Main()
{
var rand = new Random();
var twoIntStruct = new TwoStruct(new IntStruct(rand.Next()), new IntStruct(rand.Next()));
var twoInt = new TwoInt(rand.Next(), rand.Next());
Console.ReadLine();
}
public readonly struct IntStruct
{
public int Value { get; }
internal IntStruct(int value)
{
Value = value;
}
}
public class TwoStruct
{
private readonly IntStruct A;
private readonly IntStruct B;
public TwoStruct(
IntStruct a,
IntStruct b)
{
A = a;
B = b;
}
}
public class …Run Code Online (Sandbox Code Playgroud) 我正在从套接字读取一系列字节,我需要将n个字节的每个段作为项目放在结构中.
use std::mem;
#[derive(Debug)]
struct Things {
x: u8,
y: u16,
}
fn main() {
let array = [22 as u8, 76 as u8, 34 as u8];
let foobar: Things;
unsafe {
foobar = mem::transmute::<[u8; 3], Things>(array);
}
println!("{:?}", foobar);
}
Run Code Online (Sandbox Code Playgroud)
我得到的错误是24位foobar时的32位错误array.不应该foobar是24位(8 + 16 = 24)?
可能重复:
内存对齐的目的
我在网上阅读了一些关于内存对齐的文章,并且可以理解,通过正确对齐的内存(采用2字节对齐),我们可以一次性快速获取数据.
但是如果我们有像一个硬件一样的内存,那么给定一个地址,为什么我们不能直接从该位置读取2字节.喜欢:
我考虑过它.我认为,如果记忆在奇偶组中,那么理论就适用了.

我错过了什么?
我在Ubuntu 12.10 x86_64上使用gcc版本4.7.2.
首先是我终端上数据类型的大小:
sizeof(char) = 1
sizeof(short) = 2 sizeof(int) = 4
sizeof(long) = 8 sizeof(long long) = 8
sizeof(float) = 4 sizeof(double) = 8
sizeof(long double) = 16
Run Code Online (Sandbox Code Playgroud)
现在请看一下这段代码:
int main(void)
{
char c = 'a';
printf("&c = %p\n", &c);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如果我没有错,我们无法预测任何有关地址的信息c.但每次这个程序给出一些随机的十六进制地址f.因此,下一个可用位置将是一些以十六进制结束的值0.在其他数据类型的情况下我也观察到了这种模式.对于int值,地址是以十进制结尾的十六进制值c.对于double,它是以结束的一些随机十六进制值8,依此类推.
所以我在这里有2个问题.
1)谁在管理这种内存分配?是gcc还是C标准?
2)无论是谁,为什么会这样?为什么变量的存储方式是下一个可用的内存位置以十六进制值结束0?任何特定的好处?
现在请看一下这段代码:
int main(void)
{
double a = 10.2;
int b = 20;
char c = 30;
short d = …Run Code Online (Sandbox Code Playgroud) 语境:
我正在审查一些代码,这些代码将IO描述符中的数据接收到字符缓冲区中,对其进行一些控制,然后使用部分接收缓冲区来填充结构,并突然想知道是否可能涉及严格的别名规则违规.
这是一个简化版本
#define BFSZ 1024
struct Elt {
int id;
...
};
unsigned char buffer[BFSZ];
int sz = read(fd, buffer, sizeof(buffer)); // correctness control omitted for brievety
// search the beginning of struct data in the buffer, and process crc control
unsigned char *addr = locate_and_valid(buffer, sz);
struct Elt elt;
memcpy(&elt, addr, sizeof(elt)); // populates the struct
// and use it
int id = elt.id;
...
Run Code Online (Sandbox Code Playgroud)
到现在为止还挺好.提供缓冲区确实包含结构的有效表示 - 假设它已在同一平台上生成,因此没有字节顺序或填充问题 - memcpy调用已填充结构并且可以安全地使用它.
问题:
如果结构是动态分配的,则它没有声明的类型.让我们将最后一行替换为:
struct Elt *elt = malloc(sizeof(struct …Run Code Online (Sandbox Code Playgroud)