诚然,我不明白.假设您的内存中包含长度为1个字节的内存字.为什么不能在未对齐地址的单个内存访问中访问一个4字节长的变量(即不能被4整除),因为对齐地址就是这种情况?
GCC或glibc中是否有任何标准化函数在对齐指针处分配内存块?像MSVC中的_align_malloc()一样?
这是我通常用于通过Visual Studio和GCC获得对齐内存的代码
inline void* aligned_malloc(size_t size, size_t align) {
void *result;
#ifdef _MSC_VER
result = _aligned_malloc(size, align);
#else
if(posix_memalign(&result, align, size)) result = 0;
#endif
return result;
}
inline void aligned_free(void *ptr) {
#ifdef _MSC_VER
_aligned_free(ptr);
#else
free(ptr);
#endif
}
Run Code Online (Sandbox Code Playgroud)
这个代码一般是好的吗?我也见过人们用_mm_malloc,_mm_free.在大多数情况下,我想要对齐内存,使用SSE/AVX.我可以一般使用这些功能吗?它会使我的代码更简单.
最后,创建我自己的函数来对齐内存很容易(见下文).为什么会有这么多不同的常用函数来获得对齐的内存(其中许多只能在一个平台上运行)?
此代码执行16字节对齐.
float* array = (float*)malloc(SIZE*sizeof(float)+15);
// find the aligned position
// and use this pointer to read or write data into array
float* alignedArray = (float*)(((unsigned long)array + 15) & (~0x0F));
// dellocate memory …Run Code Online (Sandbox Code Playgroud) 有没有办法在C中对齐指针?假设我正在将数据写入数组堆栈(因此指针向下移动)并且我希望我写入的下一个数据是4对齐的,因此数据写入的内存位置是4的倍数,我该怎么做那?
我有
uint8_t ary[1024];
ary = ary+1024;
ary -= /* ... */
Run Code Online (Sandbox Code Playgroud)
现在假设ary在位置点0x05.我希望它指向0x04.现在我可以做到
ary -= (ary % 4);
Run Code Online (Sandbox Code Playgroud)
但是C不允许模数指针.有没有与架构无关的解决方案?
如何分配与C中特定边界对齐的内存(例如,缓存行边界)?我正在寻找malloc/free类似的实现,理想情况下尽可能便携 - 至少在32位和64位架构之间.
编辑添加:换句话说,我正在寻找一些表现得像(现在过时的?)memalign函数的东西,它可以免费使用.
这是一个可以将char数组与任何数据类型一起使用的后续内容吗?
我知道动态内存和malloc的常见实现,可以在维基百科上找到引用.我也知道malloc返回的指针可以转换成程序员想要的任何东西,甚至没有警告,因为6.3.2.3指针中的标准状态§1
指向void的指针可以转换为指向任何不完整或对象类型的指针.指向任何不完整或对象类型的指针可能会转换为指向void的指针并再次返回; 结果应该等于原始指针.
现在的问题是假设我有没有一个独立的环境malloc和free,我怎么可以建立兼容标准的C的这两个功能的实现?
如果我对标准采取一些自由,很容易:
问题是该实现返回的指针的有效类型仍然是 char *
标准在同一段§7中说明
指向对象或不完整类型的指针可以转换为指向不同对象或不完整类型的指针.如果生成的指针未针对指向类型正确对齐,则行为未定义.否则,当再次转换回来时,结果将等于原始指针.
这似乎不允许我假装被声明为简单字符的内容可以神奇地包含另一种类型,甚至在该数组的不同部分或同一部分中的不同时刻也可以包含不同的类型.不同地解释引用这样的指针似乎是未定义的行为,并严格解释标准.这就是为什么memcpy当你在字符串缓冲区中获得对象的字节表示时,例如当你从网络流中读取它时,常用的习惯用法而不是别名.
那么如何在纯C中构建一个符合malloc的实现呢?
这不是作业,这纯粹是为了我自己的个人教育.
我无法弄清楚如何实现一个对齐的malloc所以在网上查找并找到了这个网站.为方便阅读,我将发布以下代码:
#include <stdlib.h>
#include <stdio.h>
void* aligned_malloc(size_t required_bytes, size_t alignment)
{
void* p1; // original block
void** p2; // aligned block
int offset = alignment - 1 + sizeof(void*);
if ((p1 = (void*)malloc(required_bytes + offset)) == NULL)
{
return NULL;
}
p2 = (void**)(((size_t)(p1) + offset) & ~(alignment - 1));
p2[-1] = p1;
return p2;
}
void aligned_free(void *p)
{
free(((void**)p)[-1]);
}
void main (int argc, char *argv[])
{
char **endptr;
int *p = aligned_malloc (100, strtol(argv[1], …Run Code Online (Sandbox Code Playgroud) 我正在构建一个使用SSE内在函数的类层次结构,因此该类的一些成员需要16字节对齐.对于我可以使用的堆栈实例__declspec(align(#)),如下所示:
typedef __declspec(align(16)) float Vector[4];
class MyClass{
...
private:
Vector v;
};
Run Code Online (Sandbox Code Playgroud)
现在,因为__declspec(align(#))是一个编译指令,下面的代码可能会导致堆上的未对齐的Vector实例:
MyClass *myclass = new MyClass;
Run Code Online (Sandbox Code Playgroud)
这也是,我知道我可以通过重载新的和删除操作符来轻松解决使用_aligned_malloc和_aligned_free相应的问题.像这样:
//inside MyClass:
public:
void* operator new (size_t size) throw (std::bad_alloc){
void * p = _aligned_malloc(size, 16);
if (p == 0) throw std::bad_alloc()
return p;
}
void operator delete (void *p){
MyClass* pc = static_cast<MyClass*>(p);
_aligned_free(p);
}
...
Run Code Online (Sandbox Code Playgroud)
到目前为止一切都很好..但这是我的问题.请考虑以下代码:
class NotMyClass{ //Not my code, which I have little or no …Run Code Online (Sandbox Code Playgroud) 我想修改一个数组分配:
float * a = new float[n] ;
Run Code Online (Sandbox Code Playgroud)
使用对齐的分配器。我倾向于尝试使用placement new 和posix_memalign(或新的c++11 等价物),但看到placement new with arrays 在数组分配方面存在问题,因为编译器可能需要为计数或其他元数据提供额外的存储空间。
我试过:
int main()
{
float * a = new alignas(16) float[3] ;
a[2] = 0.0 ;
return a[2] ;
}
Run Code Online (Sandbox Code Playgroud)
但编译器似乎表明 alignas 被忽略:
$ g++ -std=c++11 t.cc -Werror
t.cc: In function ‘int main()’:
t.cc:4:39: error: attribute ignored [-Werror=attributes]
float * a = new alignas(16) float[3] ;
^
t.cc:4:39: note: an attribute that appertains to a type-specifier is ignored
Run Code Online (Sandbox Code Playgroud)
看起来使用 alignas …