aligned_alloc.h 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. // Copyright 2010 Google Inc. All rights reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. //
  15. // Poor man's platform-independent implementation of aligned memory allocator.
  16. #ifndef CRCUTIL_ALIGNED_ALLOC_H_
  17. #define CRCUTIL_ALIGNED_ALLOC_H_
  18. #include "std_headers.h" // size_t, ptrdiff_t
  19. namespace crcutil {
  20. // Allocates a block of memory of "size" bytes so that a field
  21. // at "field_offset" is aligned on "align" boundary.
  22. //
  23. // NB #1: "align" shall be exact power of two.
  24. //
  25. // NB #2: memory allocated by AlignedAlloc should be release by AlignedFree().
  26. //
  27. inline void *AlignedAlloc(size_t size,
  28. size_t field_offset,
  29. size_t align,
  30. const void **allocated_mem) {
  31. if (align == 0 || (align & (align - 1)) != 0 || align < sizeof(char *)) {
  32. align = sizeof(*allocated_mem);
  33. }
  34. size += align - 1 + sizeof(*allocated_mem);
  35. char *allocated_memory = new char[size];
  36. char *aligned_memory = allocated_memory + sizeof(*allocated_mem);
  37. field_offset &= align - 1;
  38. size_t actual_alignment =
  39. reinterpret_cast<size_t>(aligned_memory + field_offset) & (align - 1);
  40. if (actual_alignment != 0) {
  41. aligned_memory += align - actual_alignment;
  42. }
  43. reinterpret_cast<char **>(aligned_memory)[-1] = allocated_memory;
  44. if (allocated_mem != NULL) {
  45. *allocated_mem = allocated_memory;
  46. }
  47. return aligned_memory;
  48. }
  49. // Frees memory allocated by AlignedAlloc().
  50. inline void AlignedFree(void *aligned_memory) {
  51. if (aligned_memory != NULL) {
  52. char *allocated_memory = reinterpret_cast<char **>(aligned_memory)[-1];
  53. delete[] allocated_memory;
  54. }
  55. }
  56. } // namespace crcutil
  57. #endif // CRCUTIL_ALIGNED_ALLOC_H_