Saya baru saja menyelesaikan tes sebagai bagian dari wawancara kerja, dan satu pertanyaan mengejutkan saya, bahkan menggunakan Google untuk referensi. Saya ingin melihat apa yang dapat dilakukan oleh kru StackOverflow dengannya:
The
memset_16aligned
Fungsi membutuhkan 16-byte selaras pointer berlalu untuk itu, atau akan crash.a) Bagaimana Anda mengalokasikan 1024 byte memori, dan menyelaraskannya ke batas 16 byte?
b) Bebaskan memori setelahmemset_16aligned
eksekusi.
{
void *mem;
void *ptr;
// answer a) here
memset_16aligned(ptr, 0, 1024);
// answer b) here
}
c
memory-management
JimDaniel
sumber
sumber
Jawaban:
Jawaban asli
Jawaban tetap
Penjelasan seperti yang diminta
Langkah pertama adalah mengalokasikan ruang cadangan yang cukup, untuk berjaga-jaga. Karena memori harus selaras 16-byte (artinya alamat byte utama harus kelipatan 16), menambahkan 16 byte tambahan menjamin bahwa kami memiliki cukup ruang. Di suatu tempat di 16 byte pertama, ada pointer 16 byte yang disejajarkan. (Perhatikan bahwa
malloc()
seharusnya mengembalikan pointer yang cukup baik selaras untuk setiap . Tujuan Namun, arti dari 'setiap' terutama untuk hal-hal seperti dasar jenis -long
,double
,long double
,long long
., Dan pointer ke objek dan pointer ke fungsi Bila Anda melakukan hal-hal yang lebih khusus, seperti bermain dengan sistem grafis, mereka dapat membutuhkan lebih banyak keselarasan yang ketat daripada sistem lainnya - karenanya pertanyaan dan jawaban seperti ini.)Langkah selanjutnya adalah mengonversi void pointer ke char pointer; Meskipun demikian, GCC, Anda tidak seharusnya melakukan aritmatika penunjuk pada pointer kosong (dan GCC memiliki opsi peringatan untuk memberi tahu Anda ketika Anda menyalahgunakannya). Kemudian tambahkan 16 ke pointer mulai. Misalkan
malloc()
mengembalikan Anda pointer yang sangat tidak selaras: 0x800001. Menambahkan 16 memberi 0x800011. Sekarang saya ingin membulatkan batas 16-byte - jadi saya ingin mengatur ulang 4 bit terakhir ke 0. 0x0F memiliki 4 bit terakhir yang disetel menjadi satu; oleh karena itu,~0x0F
tetapkan semua bit ke satu kecuali empat terakhir. Anding itu dengan 0x800011 memberi 0x800010. Anda dapat beralih dari offset lain dan melihat bahwa aritmatika yang sama berfungsi.Langkah terakhir,,
free()
mudah: Anda selalu, dan hanya, kembali kefree()
nilai yang salah satunyamalloc()
,calloc()
ataurealloc()
kembali kepada Anda - hal lain adalah bencana. Anda menyediakan dengan benarmem
untuk memegang nilai itu - terima kasih. Gratis merilisnya.Akhirnya, jika Anda tahu tentang internal
malloc
paket sistem Anda, Anda bisa menebak bahwa itu mungkin mengembalikan data sejajar 16-byte (atau mungkin sejajar 8-byte). Jika sejajar 16 byte, maka Anda tidak perlu bingung dengan nilai-nilai tersebut. Namun, ini cerdik dan non-portabel -malloc
paket lain memiliki keberpihakan minimum yang berbeda, dan oleh karena itu mengasumsikan satu hal ketika melakukan sesuatu yang berbeda akan menyebabkan dump inti. Dalam batas luas, solusi ini portabel.Orang lain disebut
posix_memalign()
sebagai cara lain untuk mendapatkan memori yang selaras; yang tidak tersedia di mana-mana, tetapi seringkali dapat diimplementasikan menggunakan ini sebagai dasar. Perhatikan bahwa itu nyaman bahwa perataan adalah kekuatan 2; keberpihakan lainnya berantakan.Satu komentar lagi - kode ini tidak memeriksa apakah alokasi berhasil.
Amandemen
Windows Programmer menunjukkan bahwa Anda tidak dapat melakukan operasi topeng bit pada pointer, dan, memang, GCC (3.4.6 dan 4.3.1 diuji) tidak mengeluh seperti itu. Jadi, versi kode dasar yang diubah - diubah menjadi program utama, mengikuti. Saya juga mengambil kebebasan untuk menambahkan hanya 15 bukan 16, seperti yang telah ditunjukkan. Saya menggunakan
uintptr_t
karena C99 sudah ada cukup lama untuk dapat diakses di sebagian besar platform. Jika bukan karena penggunaanPRIXPTR
dalamprintf()
pernyataan, itu sudah cukup untuk#include <stdint.h>
bukan menggunakan#include <inttypes.h>
. [Kode ini termasuk perbaikan yang ditunjukkan oleh CR , yang mengulangi poin yang pertama kali dibuat oleh Bill K beberapa tahun yang lalu, yang berhasil saya abaikan sampai sekarang.]Dan ini adalah versi yang sedikit lebih umum, yang akan bekerja untuk ukuran yang merupakan kekuatan 2:
Untuk mengkonversi
test_mask()
ke fungsi alokasi tujuan umum, nilai pengembalian tunggal dari pengalokasi harus meng-encode alamat rilis, seperti yang ditunjukkan beberapa orang dalam jawaban mereka.Masalah dengan pewawancara
Uri berkomentar: Mungkin saya mengalami masalah pemahaman membaca pagi ini, tetapi jika pertanyaan wawancara secara khusus mengatakan: "Bagaimana Anda mengalokasikan 1024 byte memori" dan Anda jelas mengalokasikan lebih dari itu. Bukankah itu merupakan kegagalan otomatis dari pewawancara?
Respons saya tidak akan cocok dengan komentar 300 karakter ...
Tergantung, kurasa. Saya pikir kebanyakan orang (termasuk saya) mengambil pertanyaan yang berarti "Bagaimana Anda mengalokasikan ruang di mana 1024 byte data dapat disimpan, dan di mana alamat basis adalah kelipatan 16 byte". Jika pewawancara benar-benar bermaksud bagaimana Anda dapat mengalokasikan 1024 byte (hanya) dan membuatnya sejajar 16-byte, maka opsi lebih terbatas.
Namun, jika pewawancara mengharapkan salah satu dari tanggapan tersebut, saya berharap mereka mengenali bahwa solusi ini menjawab pertanyaan yang terkait erat, dan kemudian membingkai ulang pertanyaan mereka untuk mengarahkan percakapan ke arah yang benar. (Lebih jauh, jika pewawancara benar-benar stroppy, maka saya tidak akan menginginkan pekerjaan itu; jika jawaban terhadap persyaratan yang tidak tepat akurat ditembak jatuh dalam api tanpa koreksi, maka pewawancara bukanlah seseorang yang aman untuk bekerja.)
Dunia bergerak
Judul pertanyaan telah berubah baru-baru ini. Itu Memecahkan keselarasan memori di C pertanyaan wawancara yang bingung saya . Judul yang direvisi ( Bagaimana cara mengalokasikan memori selaras hanya menggunakan perpustakaan standar? ) Menuntut jawaban yang sedikit direvisi - adendum ini menyediakannya.
C11 (ISO / IEC 9899: 2011) menambahkan fungsi
aligned_alloc()
:Dan POSIX mendefinisikan
posix_memalign()
:Salah satu atau keduanya dapat digunakan untuk menjawab pertanyaan sekarang, tetapi hanya fungsi POSIX yang menjadi pilihan ketika pertanyaan itu awalnya dijawab.
Di belakang layar, fungsi memori selaras baru melakukan pekerjaan yang sama seperti yang dijelaskan dalam pertanyaan, kecuali mereka memiliki kemampuan untuk memaksa penyelarasan lebih mudah, dan melacak dimulainya memori selaras secara internal sehingga kode tidak harus berurusan dengan khusus - itu hanya membebaskan memori yang dikembalikan oleh fungsi alokasi yang digunakan.
sumber
<inttypes.h>
dari C99 tersedia (setidaknya untuk string format - bisa dibilang, nilai-nilai harus dilewatkan dengan pemain:)(uintptr_t)mem, (uintptr_t)ptr
. String format bergantung pada penggabungan string dan makro PRIXPTR adalahprintf()
specifier panjang dan tipe yang benar untuk output hex untuk suatuuintptr_t
nilai. Alternatifnya adalah menggunakan%p
tetapi output dari itu bervariasi berdasarkan platform (beberapa menambahkan yang terkemuka0x
, sebagian besar tidak) dan biasanya ditulis dengan angka hex kecil, yang tidak saya sukai; apa yang saya tulis adalah seragam di seluruh platform.Tiga jawaban yang sedikit berbeda tergantung bagaimana Anda melihat pertanyaan:
1) Cukup bagus untuk pertanyaan persis yang diajukan adalah solusi Jonathan Leffler, kecuali untuk mengumpulkan hingga 16-aligned, Anda hanya perlu 15 byte tambahan, bukan 16.
SEBUAH:
B:
2) Untuk fungsi alokasi memori yang lebih umum, penelepon tidak ingin harus melacak dua pointer (satu untuk digunakan dan satu lagi untuk membebaskan). Jadi, Anda menyimpan pointer ke buffer 'asli' di bawah buffer yang diselaraskan.
SEBUAH:
B:
Perhatikan bahwa tidak seperti (1), di mana hanya 15 byte ditambahkan ke mem, kode ini benar-benar dapat mengurangi penyelarasan jika implementasi Anda terjadi untuk menjamin penyelarasan 32 byte dari malloc (tidak mungkin, tetapi secara teori implementasi C dapat memiliki 32 byte jenis selaras). Itu tidak masalah jika semua yang Anda lakukan adalah memanggil memset_16aligned, tetapi jika Anda menggunakan memori untuk struct maka itu bisa jadi masalah.
Saya tidak yakin apa perbaikan yang baik untuk ini (selain untuk memperingatkan pengguna bahwa buffer yang dikembalikan belum tentu cocok untuk struct sewenang-wenang) karena tidak ada cara untuk menentukan secara programatik apa jaminan penyelarasan implementasi khusus. Saya kira pada saat startup Anda dapat mengalokasikan dua atau lebih buffer 1-byte, dan menganggap bahwa alignment terburuk yang Anda lihat adalah alignment yang dijamin. Jika Anda salah, Anda membuang-buang memori. Siapa pun yang memiliki ide yang lebih baik, katakan saja ...
[ Ditambahkan : Trik 'standar' adalah untuk membuat penyatuan 'jenis yang kemungkinan akan disejajarkan secara maksimal' untuk menentukan perataan yang diperlukan. Tipe yang disejajarkan secara maksimal kemungkinan besar adalah (dalam C99) '
long long
', 'long double
', 'void *
', atau 'void (*)(void)
'; jika Anda menyertakan<stdint.h>
, Anda mungkin bisa menggunakan 'intmax_t
' sebagai penggantilong long
(dan, pada mesin Power 6 (AIX),intmax_t
akan memberi Anda tipe integer 128-bit). Persyaratan penyelarasan untuk serikat itu dapat ditentukan dengan menanamkannya ke dalam sebuah struct dengan satu char yang diikuti oleh serikat pekerja:Anda kemudian akan menggunakan yang lebih besar dari perataan yang diminta (dalam contoh, 16) dan
align
nilai yang dihitung di atas.Pada (64-bit) Solaris 10, tampak bahwa penyelarasan dasar untuk hasil dari
malloc()
adalah kelipatan 32 byte.]
Dalam praktiknya, pengalokasi yang selaras sering mengambil parameter untuk penyelarasan alih-alih bawaan. Jadi pengguna akan lulus dalam ukuran struct yang mereka pedulikan (atau kekuatan paling sedikit 2 lebih besar dari atau sama dengan itu) dan semua akan baik-baik saja.
3) Gunakan apa yang disediakan platform Anda:
posix_memalign
untuk POSIX,_aligned_malloc
di Windows.4) Jika Anda menggunakan C11, maka opsi terbersih - portabel dan ringkas - adalah menggunakan fungsi pustaka standar
aligned_alloc
yang diperkenalkan dalam versi spesifikasi bahasa ini.sumber
ASSERT(mem);
untuk memeriksa hasil alokasi;assert
adalah untuk menangkap kesalahan pemrograman dan tidak kekurangan sumber daya run-time.char *
dansize_t
akan menghasilkan kesalahan. Anda harus menggunakan sesuatu sepertiuintptr_t
.Anda juga bisa mencoba
posix_memalign()
(pada platform POSIX, tentu saja).sumber
Inilah pendekatan alternatif untuk bagian 'pembulatan'. Bukan solusi yang paling dikodekan tetapi menyelesaikan pekerjaan, dan jenis sintaksis ini sedikit lebih mudah diingat (ditambah akan bekerja untuk nilai penyelarasan yang bukan kekuatan 2). Para
uintptr_t
pemain diperlukan untuk menenangkan kompiler; pointer aritmatika tidak terlalu menyukai pembagian atau perkalian.sumber
Sayangnya, di C99 tampaknya cukup sulit untuk menjamin penyelarasan dalam bentuk apa pun dengan cara yang portabel di setiap implementasi C yang sesuai dengan C99. Mengapa? Karena pointer tidak dijamin menjadi "alamat byte" yang mungkin dibayangkan dengan model memori datar. Representasi dari uintptr_t juga tidak dijamin, yang merupakan tipe opsional.
Kita mungkin tahu beberapa implementasi yang menggunakan representasi untuk void * (dan menurut definisi, juga char * ) yang merupakan alamat byte sederhana, tetapi oleh C99 itu tidak jelas bagi kita, para programmer. Sebuah implementasi mungkin mewakili sebuah pointer oleh set { segment , offset } di mana offset bisa memiliki keselarasan siapa-tahu-apa "dalam kenyataan." Mengapa, sebuah pointer bahkan bisa berupa nilai pencarian tabel hash, atau bahkan nilai pencarian daftar-tertaut. Itu bisa menyandikan informasi batas.
Dalam konsep C1X terbaru untuk Standar C, kita melihat kata kunci _Alignas . Itu mungkin sedikit membantu.
Satu-satunya jaminan yang diberikan C99 kepada kami adalah bahwa fungsi alokasi memori akan mengembalikan pointer yang cocok untuk penugasan ke pointer yang menunjuk pada jenis objek apa pun. Karena kami tidak dapat menentukan perataan objek, kami tidak dapat mengimplementasikan fungsi alokasi kami sendiri dengan tanggung jawab untuk penyelarasan dengan cara portabel yang terdefinisi dengan baik.
Akan baik salah tentang klaim ini.
sumber
aligned_alloc()
. (C ++ 11/14 / 1z masih belum memilikinya)._Alignas()
dan C ++alignas()
tidak melakukan apa pun untuk alokasi dinamis, hanya untuk penyimpanan otomatis dan statis (atau tata letak struct).Di depan padding count-16 16 vs 15, angka aktual yang perlu Anda tambahkan untuk mendapatkan keselarasan N adalah maks (0, NM) di mana M adalah penyelarasan alami dari pengalokasi memori (dan keduanya adalah kekuatan 2).
Karena penyelarasan memori minimal dari setiap pengalokasi adalah 1 byte, 15 = maks (0,16-1) adalah jawaban yang konservatif. Namun, jika Anda tahu pengalokasi memori Anda akan memberi Anda alamat sejajar 32-bit (yang cukup umum), Anda bisa menggunakan 12 sebagai pad.
Ini tidak penting untuk contoh ini tetapi mungkin penting pada sistem tertanam dengan 12K RAM di mana setiap int disimpan.
Cara terbaik untuk mengimplementasikannya jika Anda benar-benar akan mencoba untuk menyimpan setiap byte yang mungkin adalah sebagai makro sehingga Anda dapat memberinya makan perataan memori asli Anda. Sekali lagi, ini mungkin hanya berguna untuk sistem embedded di mana Anda perlu menyimpan setiap byte.
Dalam contoh di bawah ini, pada sebagian besar sistem, nilai 1 baik-baik saja
MEMORY_ALLOCATOR_NATIVE_ALIGNMENT
, namun untuk sistem tertanam teoritis kami dengan alokasi rata-rata 32-bit, berikut ini dapat menghemat sedikit memori berharga:sumber
Mungkin mereka akan puas dengan pengetahuan tentang memalign ? Dan seperti yang ditunjukkan Jonathan Leffler, ada dua fungsi baru yang lebih disukai untuk diketahui.
Ups, florin mengalahkan saya untuk itu. Namun, jika Anda membaca halaman manual yang saya tautkan, kemungkinan besar Anda akan memahami contoh yang diberikan oleh poster sebelumnya.
sumber
memalign
Fungsi ini sudah usang danaligned_alloc
atauposix_memalign
harus digunakan sebagai gantinya". Saya tidak tahu apa yang dikatakannya pada Oktober 2008 - tetapi mungkin tidak disebutkanaligned_alloc()
karena ditambahkan ke C11.Kami melakukan hal semacam ini sepanjang waktu untuk Accelerate.framework, perpustakaan OS X / iOS yang sangat vektor, di mana kami harus memperhatikan penyelarasan sepanjang waktu. Ada beberapa opsi, satu atau dua di antaranya tidak saya lihat di atas.
Metode tercepat untuk array kecil seperti ini hanya menempelkannya di stack. Dengan GCC / dentang:
Tidak diperlukan gratis (). Ini biasanya dua instruksi: kurangi 1024 dari stack pointer, lalu AND stack pointer dengan -alignment. Mungkin pemohon membutuhkan data pada heap karena umur array melebihi stack atau rekursi sedang bekerja atau ruang stack berada pada premium yang serius.
Pada OS X / iOS semua panggilan ke malloc / calloc / dll. selalu selaras 16 byte. Jika Anda membutuhkan 32 byte yang diluruskan untuk AVX, misalnya, maka Anda dapat menggunakan posix_memalign:
Beberapa orang telah menyebutkan antarmuka C ++ yang bekerja sama.
Seharusnya tidak dilupakan bahwa halaman disejajarkan dengan kekuatan besar dua, jadi buffer halaman-disejajarkan juga 16 byte selaras. Dengan demikian, mmap () dan valloc () dan antarmuka serupa lainnya juga merupakan opsi. mmap () memiliki keuntungan bahwa buffer dapat dialokasikan diinisialisasi dengan sesuatu yang tidak nol di dalamnya, jika Anda mau. Karena ini memiliki ukuran selaras halaman, Anda tidak akan mendapatkan alokasi minimum dari ini, dan kemungkinan akan dikenakan kesalahan VM saat pertama kali Anda menyentuhnya.
Cheesy: Aktifkan guard malloc atau sejenisnya. Buffer yang berukuran n * 16 byte seperti ini akan disejajarkan n * 16 byte, karena VM digunakan untuk menangkap overruns dan batas-batasnya berada pada batas halaman.
Beberapa fungsi Accelerate.framework menggunakan buffer temp yang disediakan pengguna untuk digunakan sebagai ruang awal. Di sini kita harus mengasumsikan bahwa buffer yang diberikan kepada kita tidak selaras dan pengguna secara aktif berusaha membuat hidup kita sulit karena dendam. (Test case kami menempel halaman penjaga tepat sebelum dan sesudah buffer temp untuk menggarisbawahi dendam.) Di sini, kami mengembalikan ukuran minimum yang kami butuhkan untuk menjamin segmen selaras 16 byte di suatu tempat di dalamnya, dan kemudian secara manual menyelaraskan buffer sesudahnya. Ukuran ini diinginkan_ukuran + perataan - 1. Jadi, Dalam hal ini yaitu 1024 + 16 - 1 = 1039 byte. Kemudian sejajarkan seperti itu:
Menambahkan alignment-1 akan memindahkan pointer melewati alamat yang pertama dan kemudian ANDing dengan -alignment (mis. 0xfff ... ff0 untuk alignment = 16) membawanya kembali ke alamat yang disejajarkan.
Seperti dijelaskan oleh posting lain, pada sistem operasi lain tanpa jaminan penyelarasan 16-byte, Anda dapat memanggil malloc dengan ukuran yang lebih besar, menyisihkan pointer secara gratis () kemudian, menyelaraskan seperti dijelaskan di atas dan menggunakan pointer yang disejajarkan, sebanyak dijelaskan untuk kasus buffer temp kami.
Adapun aligned_memset, ini agak konyol. Anda hanya perlu mengulang hingga 15 byte untuk mencapai alamat yang selaras, dan kemudian melanjutkan dengan toko selaras setelah itu dengan beberapa kemungkinan kode pembersihan di akhir. Anda bahkan dapat melakukan bit pembersihan dalam kode vektor, baik sebagai toko yang tidak selaras yang tumpang tindih dengan wilayah yang disejajarkan (memberikan panjangnya setidaknya panjang vektor) atau menggunakan sesuatu seperti movmaskdqu. Seseorang sedang malas. Namun, itu mungkin pertanyaan wawancara yang masuk akal jika pewawancara ingin tahu apakah Anda merasa nyaman dengan stdint.h, operator bitwise dan dasar-dasar memori, sehingga contoh yang dibuat-buat dapat dimaafkan.
sumber
Aku heran tidak ada ini sebagai up Shao 's jawaban itu, seperti yang saya mengerti, tidak mungkin untuk melakukan apa yang diminta dalam standar C99, karena mengubah pointer ke tipe integral secara resmi adalah perilaku undefined. (Terlepas dari standar yang memungkinkan konversi
uintptr_t
<->void*
, tetapi standar tersebut tampaknya tidak memungkinkan melakukan manipulasiuintptr_t
nilai dan mengubahnya kembali.)sumber
unsigned char* myptr
; dan kemudian menghitung `mptr + = (16- (uintptr_t) my_ptr) & 0x0F, perilaku akan didefinisikan pada semua implementasi yang mendefinisikan my_ptr, tetapi apakah pointer yang dihasilkan akan disejajarkan akan tergantung pada pemetaan antara bit dan alamat uintptr_t.penggunaan memalign, Aligned-Memory-Blocks mungkin menjadi solusi yang baik untuk masalah tersebut.
sumber
memalign
Fungsi ini sudah usang danaligned_alloc
atauposix_memalign
harus digunakan sebagai gantinya". Saya tidak tahu apa yang dikatakannya pada Oktober 2010.Hal pertama yang muncul di kepala saya ketika membaca pertanyaan ini adalah untuk mendefinisikan struct yang selaras, instantiate, dan kemudian arahkan ke itu.
Apakah ada alasan mendasar saya kehilangan karena tidak ada orang lain yang menyarankan ini?
Sebagai sidenote, karena saya menggunakan array char (dengan asumsi char sistem adalah 8 bit (yaitu 1 byte)), saya tidak melihat perlunya
__attribute__((packed))
(mengoreksi saya jika saya salah), tapi saya katakan dengan cara apapun.Ini bekerja pada dua sistem yang saya coba, tetapi ada kemungkinan bahwa ada optimisasi kompiler yang saya tidak sadari memberi saya positif palsu berhadapan dengan kemanjuran kode. Saya menggunakan
gcc 4.9.2
OSX dangcc 5.2.1
Ubuntu.sumber
Khusus MacOS X:
C11 didukung, jadi Anda bisa memanggil aligned_malloc (16, size).
MacOS X mengambil kode yang dioptimalkan untuk masing-masing prosesor pada saat boot untuk memset, memcpy dan memmove dan kode itu menggunakan trik yang belum pernah Anda dengar untuk membuatnya cepat. 99% kemungkinan memset berjalan lebih cepat daripada memset tulisan tangan16 yang membuat seluruh pertanyaan tidak ada gunanya.
Jika Anda menginginkan solusi portabel 100%, sebelum C11 tidak ada. Karena tidak ada cara portabel untuk menguji keselarasan pointer. Jika tidak harus 100% portabel, Anda dapat menggunakannya
Ini mengasumsikan bahwa penyelarasan pointer disimpan dalam bit terendah ketika mengkonversi pointer ke unsigned int. Konversi ke int yang tidak ditandatangani kehilangan informasi dan implementasi didefinisikan, tetapi itu tidak masalah karena kami tidak mengubah hasilnya kembali menjadi sebuah pointer.
Bagian yang mengerikan tentu saja bahwa pointer asli harus disimpan di suatu tempat untuk memanggil bebas () dengannya. Jadi semuanya saya benar-benar meragukan kearifan desain ini.
sumber
aligned_malloc
di OS X? Saya menggunakan Xcode 6.1 dan tidak didefinisikan di mana pun di iOS SDK, juga tidak dinyatakan di mana pun di/usr/include/*
.aligned_alloc()
,, tapi itu juga tidak dideklarasikan. Dari GCC 5.3.0, saya mendapatkan pesan yang menarikalig.c:7:15: error: incompatible implicit declaration of built-in function ‘aligned_alloc’ [-Werror]
danalig.c:7:15: note: include ‘<stdlib.h>’ or provide a declaration of ‘aligned_alloc’
. Kode melakukan memang termasuk<stdlib.h>
, tetapi tidak-std=c11
juga-std=gnu11
mengubah pesan kesalahan.Anda juga dapat menambahkan 16 byte dan kemudian mendorong ptr asli ke 16bit sejajar dengan menambahkan (16-mod) seperti di bawah penunjuk:
sumber
Jika ada kendala, Anda tidak dapat membuang satu byte, maka solusi ini berfungsi: Catatan: Ada kasus di mana ini dapat dieksekusi tanpa batas: D
sumber
%
operator didefinisikanvoid*
dengan cara yang bermakna?Untuk solusinya saya menggunakan konsep padding yang menyelaraskan memori dan jangan buang memori satu byte.
Jika ada kendala itu, Anda tidak bisa membuang satu byte. Semua pointer yang dialokasikan dengan malloc selaras 16 byte.
C11 didukung, jadi Anda bisa langsung menelepon
aligned_alloc (16, size)
.sumber
malloc()
memang selaras pada batas 16-byte, tetapi tidak ada dalam standar apa pun yang menjamin - itu hanya akan cukup selaras dengan baik untuk penggunaan apa pun, dan pada banyak sistem 32-bit menyelaraskan pada Batas 8-byte sudah cukup, dan bagi sebagian orang, batas 4-byte sudah cukup.Semoga yang ini adalah implementasi paling sederhana, beri tahu saya komentar Anda.
sumber
sumber
add += 16 - (add % 16)
.(2 - (2 % 16)) == 0
.