2010-05-10 20 views
7

Tôi đang phát triển một thư viện mục đích chung trong đó sử dụng Win32 của HeapAllocalignment gì HeapAlloc sử dụng

MSDN không đề cập đến đảm bảo sự liên kết cho HeapAlloc Win32, nhưng tôi thực sự cần phải biết những gì sắp xếp nó sử dụng, vì vậy tôi có thể tránh được quá nhiều đệm.

Trên máy tính của tôi (vista, x86), tất cả phân bổ đều được căn chỉnh ở 8 byte. Điều này cũng đúng cho các nền tảng khác không?

+6

Nếu MSDN không nói, thì * không có bảo đảm *. Ngay cả khi bạn hỏi 1000 người và tất cả họ đều xác định 8 byte trên máy của họ, đó không phải là sự đảm bảo và bạn có lẽ không nên dựa vào nó. –

+0

Tôi đồng ý với các điều khoản trên. Bạn có thể muốn xem http://blogs.msdn.com/oldnewthing/archive/2007/12/27/6873648.aspx để xem liệu nó có liên quan hay không. – torak

+1

Tôi đồng ý, không có sự đảm bảo nào, nhưng tôi không yêu cầu bảo đảm ở đây: Tôi đang xin kinh nghiệm. Tôi tự tin rằng Microsoft sẽ không bao giờ giảm sự liên kết dưới 8 byte, bởi vì đôi sẽ không thể đọc được nữa. Tôi chỉ muốn biết điều đó cũng đúng với các nền tảng nhúng. – Ondergetekende

Trả lời

2

Chức năng HeapAlloc không chỉ định liên kết đảm bảo trong trang MSDN, nhưng tôi có xu hướng nghĩ rằng nó phải có cùng một đảm bảo của GlobalAlloc, được đảm bảo trả về bộ nhớ 8 byte (mặc dù dựa vào trên các tính năng không có giấy tờ là tà ác); sau khi tất cả, nó nói rõ ràng rằng Global/LocalAlloc chỉ là hàm bao quanh HeapAlloc (mặc dù chúng có thể loại bỏ các byte n đầu tiên để có được bộ nhớ liên kết - nhưng tôi nghĩ rằng nó rất khó).

Nếu bạn thực sự muốn chắc chắn, chỉ cần sử dụng GlobalAlloc, hoặc thậm chí VirtualAlloc, có mức độ chi tiết của trang, thường là 4 KB (IIRC), nhưng trong trường hợp này, bạn sẽ lãng phí rất nhiều ký ức.

Nhân tiện, nếu bạn sử dụng toán tử C++ mới, bạn được đảm bảo để liên kết bộ nhớ đúng với loại bạn đã chỉ định: đây có thể là cách để đi.

1

Căn chỉnh sẽ sao cho địa chỉ trả lại có thể được truyền tới con trỏ thuộc bất kỳ loại nào. Nếu không, bạn sẽ không thể sử dụng bộ nhớ trong ứng dụng của mình.

+0

Nếu tôi hiểu chính xác câu trả lời của bạn, thực tế là địa chỉ trả lại có thể được đúc thành một con trỏ thuộc bất kỳ loại nào không liên quan đến căn chỉnh của bộ nhớ được cấp phát. –

+0

@Matteo: liên quan. Nếu nó không được căn chỉnh cho một kiểu T, thì một diễn viên vào 'T *' sẽ không hợp lệ (nó sẽ biên dịch, nhưng nó sẽ không được đảm bảo để hoạt động). Vì vậy, bởi vì nó có thể được đúc thành bất kỳ loại nào, nó phải được căn chỉnh đủ nghiêm ngặt để làm việc với bất kỳ loại nào. – jalf

+0

Ok, tôi hiểu câu trả lời của bạn theo một cách khác, vì vậy những gì tôi đã nói trước đây không áp dụng; vẫn còn, hệ điều hành không thể đảm bảo rằng nó được liên kết cho * bất kỳ * loại, nếu không chỉ có một con trỏ NULL sẽ được ok :). Có lẽ nó được đảm bảo để làm việc cho loại lớn nhất mà đòi hỏi sự liên kết được biết đến với những người đã viết các cấp phát (hoặc loại lớn nhất mà đòi hỏi sự liên kết mà những người đã viết các cấp phát sẵn sàng hỗ trợ trực tiếp). –

3

Đáng ngạc nhiên, Google lần lượt lên evidence rằng HeapAlloc không phải lúc nào cũng SSE-compliant:

HeapAlloc() có tất cả các đối tượng liên kết luôn 8-byte, không có vấn đề gì kích thước của chúng là (nhưng không phải 16-byte - được gán cho SSE).

Bài đăng từ giữa năm 2008, cho thấy rằng Windows XP gần đây bị lỗi này.

Xem thêm http://support.microsoft.com/kb/286470:

Các nhà quản lý đống Windows (mọi phiên bản) đã luôn luôn đảm bảo rằng việc phân bổ đống có một địa chỉ bắt đầu đó là 8-byte aligned (trên nền tảng 64-bit sự liên kết là 16- byte).

+0

Yep, SSE loại sống một loại bóng tồn tại, nơi liên kết của họ hiếm khi được tôn trọng bởi chức năng phân bổ. Tôi không chắc chắn tại sao, nhưng nó có vẻ là trường hợp trên cả Windows và Linux. Theo mặc định, bạn không nhận được sự bảo đảm căn chỉnh tốt hơn 8 byte. – jalf

+0

@ jalf: lạ! Tôi nhớ lại vào năm 1999 khi AltiVec được giới thiệu, Apple đã ngay lập tức xác nhận lại chức năng phân bổ 'NewPtr' và' NewHandle' để căn chỉnh 16 byte. Nó không giống như bạn phá vỡ phần mềm cũ theo cách đó! – Potatoswatter