如何在C++項(xiàng)目中實(shí)現(xiàn)一個(gè)aligned_malloc方法-創(chuàng)新互聯(lián)

這篇文章將為大家詳細(xì)講解有關(guān)如何在C++項(xiàng)目中實(shí)現(xiàn)一個(gè)aligned_malloc方法,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個(gè)參考,希望大家閱讀完這篇文章后對相關(guān)知識(shí)有一定的了解。

紅旗網(wǎng)站建設(shè)公司創(chuàng)新互聯(lián)建站,紅旗網(wǎng)站設(shè)計(jì)制作,有大型網(wǎng)站制作公司豐富經(jīng)驗(yàn)。已為紅旗1000多家提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\成都外貿(mào)網(wǎng)站建設(shè)公司要多少錢,請找那個(gè)售后服務(wù)好的紅旗做網(wǎng)站的公司定做!

malloc的默認(rèn)行為

int main()
{
  void *p = malloc(1024);
  printf("0x%p\n", p);
  free(p);
}

請求了一個(gè)大小為1024的內(nèi)存塊并打印出來,一切都很完美。
我們看看這塊內(nèi)存的地址。

如何在C++項(xiàng)目中實(shí)現(xiàn)一個(gè)aligned_malloc方法

可以看到,在64bit機(jī)器上,malloc默認(rèn)行為會(huì)將分配的地址以16-byte對齊,如果我們想改變這種默認(rèn)行為,提供32-byte或者64-byte對齊,應(yīng)該怎么做呢?

實(shí)現(xiàn)aligned_malloc

源代碼

從C++17開始,可以使用aligned_alloc函數(shù)達(dá)到這個(gè)目的,但是如果使用較老的C++版本,如C++14,C++11,我們需要手動(dòng)寫一個(gè)實(shí)現(xiàn)。
話不多說,先貼代碼如下,aligned_malloc和aligned_free,需要配合使用,否則會(huì)有內(nèi)存泄漏問題。

#include <memory>

void* aligned_malloc(size_t size, size_t alignment)
{
	size_t offset = alignment - 1 + sizeof(void*);
	void * originalP = malloc(size + offset);
	size_t originalLocation = reinterpret_cast<size_t>(originalP);
	size_t realLocation = (originalLocation + offset) & ~(alignment - 1);
	void * realP = reinterpret_cast<void*>(realLocation);
	size_t originalPStorage = realLocation - sizeof(void*);
	*reinterpret_cast<void**>(originalPStorage) = originalP;
	return realP;
}

void aligned_free(void* p)
{
	size_t originalPStorage = reinterpret_cast<size_t>(p) - sizeof(void*);
	free(*reinterpret_cast<void**>(originalPStorage));
}

int main()
{	
	void * p = aligned_malloc(1024, 64);
	printf("0x%p\n", p);
	aligned_free(p);
	return 0;
}

添加一個(gè)測試程序,

#include <assert.h>

void TestAlignedMalloc()
{
  const int size = 100;
  const int alignment = 64;
  void* testArray[size];
  for (int i = 0; i < size; ++i)
  {
    void * p = aligned_malloc(1024, alignment);
    assert((reinterpret_cast<size_t>(p) & (alignment - 1)) == 0);
    printf("0x%p\n", p);
    testArray[i] = p;
  }
  for (int i = 0; i < size; ++i)
  {
    aligned_free(testArray[i]);
  }
}

int main()
{
  TestAlignedMalloc();
  return 0;
}

看看結(jié)果,

如何在C++項(xiàng)目中實(shí)現(xiàn)一個(gè)aligned_malloc方法

分配的內(nèi)存地址都是以64-byte為邊界,并且分配的內(nèi)存最后也被成功釋放了,函數(shù)是正確的。

源代碼說明

本小段主要向不大了解解決思路的小伙伴做一些簡單解釋,程序大佬可以一笑而過哈。

首先我們要明確我們的解決方案,既然malloc分配的指針地址不能達(dá)到我們想要的字節(jié)對齊效果,我們就自己來調(diào)整這個(gè)指針。所以我們的做法是

  • 比用戶實(shí)際需要的多分配一些內(nèi)存,多分配的部分等于對齊大小減一再加上指針大小。加上對齊大小減一很好理解,是為了之后的對齊做準(zhǔn)備,而加上指針大小是為了之后有空間保存原始指針,對應(yīng)分配函數(shù)中的前2行

  • 在malloc返回的原始指針的基礎(chǔ)上,加上指針大小,再對齊(采用的方法就是加上對齊大小減1再做位運(yùn)算),這個(gè)運(yùn)算結(jié)果就是我們想要的對齊后的指針,也是我們返回給用戶的指針,對應(yīng)分配函數(shù)中的3~5行

  • 我們還需要保存malloc返回的原始指針,否則free的時(shí)候會(huì)出問題。這時(shí)我們之前多分配的一個(gè)指針大小就有用武之地了,保存原始指針在那個(gè)地址,分配函數(shù)的最后幾行就在做這個(gè)事

  • 當(dāng)free的時(shí)候,我們知道原始指針存放在我們使用的指針的前一個(gè)指針大小偏移的內(nèi)存里面,通過一些運(yùn)算取得這個(gè)內(nèi)存地址,再根據(jù)里面存放的原始指針調(diào)用free完成內(nèi)存釋放

關(guān)于如何在C++項(xiàng)目中實(shí)現(xiàn)一個(gè)aligned_malloc方法就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。

當(dāng)前標(biāo)題:如何在C++項(xiàng)目中實(shí)現(xiàn)一個(gè)aligned_malloc方法-創(chuàng)新互聯(lián)
當(dāng)前路徑:http://bm7419.com/article16/dssjgg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供外貿(mào)網(wǎng)站建設(shè)軟件開發(fā)、定制網(wǎng)站、云服務(wù)器、營銷型網(wǎng)站建設(shè)靜態(tài)網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

網(wǎng)站建設(shè)網(wǎng)站維護(hù)公司