我刚刚完成了一项测试,作为求职面试的一部分,一个问题让我感到难过 - 甚至使用谷歌作为参考.我想看看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) 我正在尝试将现有代码调整为64位机器.主要问题是在一个函数中,前一个编码器使用void*参数,该参数在函数本身中转换为合适的类型.一个简短的例子:
void function(MESSAGE_ID id, void* param)
{
if(id == FOO) {
int real_param = (int)param;
// ...
}
}
Run Code Online (Sandbox Code Playgroud)
当然,在64位机器上,我收到错误:
error: cast from 'void*' to 'int' loses precision
Run Code Online (Sandbox Code Playgroud)
我想纠正这个问题,以便它仍然可以在32位机器上运行并且尽可能干净.任何的想法 ?
我有一个指针,ptr和一个条件,cond.我需要最快的方式重置ptr如果cond是true,还是保留ptr,如果不变cond的false.目前的实施是简单的:
void reset_if_true(void*& ptr, bool cond)
{
if (cond)
ptr = nullptr;
}
Run Code Online (Sandbox Code Playgroud)
我知道上面的代码性能很好,我不能指望优化它的主要性能提升.但是,这段代码每秒被调用数百万次,并且保存的每个小纳秒都是相关的.
我正在考虑摆脱分支的事情,例如:
void* p[] = { ptr, nullptr };
ptr = p[cond];
Run Code Online (Sandbox Code Playgroud)
但我不确定这是最好的办法.
我一直在阅读有关malloc当您请求零大小的块时的行为的讨论.
我理解malloc(0)是实现定义的行为,它应该返回一个空指针,或者我仍然不应该访问的非空指针.(这是有道理的,因为不能保证它指向任何可用的内存.)
但是,如果获得这样一个不可访问的非空指针,我是否允许以free通常的方式传递给它?或者这是非法的,因为我得到的指针malloc(0)可能不指向实际分配的内存块?
具体而言,以下代码是否具有明确定义的行为:
#include <stdio.h>
#include <stdlib.h>
int main() {
int* x = (int*) malloc(0);
if (x == NULL) {
printf("Got NULL\n");
return 0;
} else {
printf("Got nonnull %p\n", x);
}
free(x); // is calling `free` here okay?
}
Run Code Online (Sandbox Code Playgroud) C++ 11引入了alignas说明符来指定变量的对齐方式,以及alignof运算符来查询类型的默认对齐方式.但是,我没有看到任何方法来获得特定变量的对齐方式.让我们采取以下简单的例子:
alignas(16) float* array;
Run Code Online (Sandbox Code Playgroud)
以下是我们可以做的事情:
alignof(float*) 返回8,这显然不是我们想要的.alignof(array)返回16,这正是我们想要的,但这是一个编译器扩展; alignof由标准指定不能用于特定变量.alignof(decltype(array)) 返回8,这是非常期待但不是我们想要的.std::alignment_of是实施的alignof,所以它没有多大帮助.我想要一种机制来确认特定变量array是否在16字节边界上对齐.标准中是否有任何内容可以执行此类查询?
我读到你不能在指针上做bitmasks,为什么你不能对指针进行按位操作?
有没有办法达到同样的效果?
这同样适用于C++吗?
在GLib文档中,有一章关于类型转换宏.在关于转换int为*void指针的讨论中,它说(强调我的):
天真的,你可以试试这个,但这是不正确的:
Run Code Online (Sandbox Code Playgroud)gpointer p; int i; p = (void*) 42; i = (int) p;同样,该示例不正确,请勿复制.问题是在某些系统上你需要这样做:
Run Code Online (Sandbox Code Playgroud)gpointer p; int i; p = (void*) (long) 42; i = (int) (long) p;
(来源:GLib参考手册GLib 2.39.92,章节类型转换宏).
为什么演员long必要?
是否需要加宽int不作为指针演员的一部分自动发生?
我无法完全理解我在这里阅读的内容的后果:将一个int指针转换为char ptr,反之亦然
总之,这会有用吗?
set4Bytes(unsigned char* buffer) {
const uint32_t MASK = 0xffffffff;
if ((uintmax_t)buffer % 4) {//misaligned
for (int i = 0; i < 4; i++) {
buffer[i] = 0xff;
}
} else {//4-byte alignment
*((uint32_t*) buffer) = MASK;
}
}
Run Code Online (Sandbox Code Playgroud)
编辑
有一个长时间的讨论(它是在评论中,神秘地删除了)关于指针应该被铸造到什么类型以检查对齐.现在讨论这个问题.
我审阅了以下链接,
在上面的link1中,在答案中提到了" Pointers are of pointer type".
我只需要知道指针是否是数据类型.
没有人用一个单词回答这个问题.是数据类型还是没有?
这是我提到的第二个链接
指针只是一个保存地址的变量,因此人们可以争辩说指针是一种数据类型,但它没有被定义为数据类型(根据"C编程语言".Kernighan&Ritchie).