2012-02-12 31 views
5

Trong C++ khi tôi làm new (hoặc thậm chí malloc) là có bất kỳ đảm bảo rằng địa chỉ trả lại sẽ lớn hơn một giá trị nhất định? Bởi vì ... trong dự án này, tôi thấy nó rất hữu ích khi sử dụng 0-1k như là một enum. Nhưng tôi sẽ không muốn làm điều đó nếu nó có thể để có được một giá trị thấp. Hệ thống đích duy nhất của tôi là 32 hoặc 64bit CPU với cửa sổ OS/linux và mac.Con trỏ có được đảm bảo là> một giá trị nhất định không?

Tiêu chuẩn có nói gì về con trỏ không? Có cửa sổ hoặc Linux nói bất cứ điều gì về thời gian chạy C của họ và những gì địa chỉ bộ nhớ thấp nhất (cho ram) là?

-edit- i kết thúc việc sửa đổi quá tải new của mình để kiểm tra xem địa chỉ có ở trên> 1k không. Tôi gọi std :: chấm dứt nếu nó không.

+1

Tại sao bạn sử dụng enums làm con trỏ? – Pubby

+1

@Pubby: Phổ biến (đặc biệt là trong phiên dịch và trò chơi) dựa trên đặc điểm con trỏ cụ thể theo nền tảng để thêm thông tin vào chúng, thường là loại bỏ tính không giới hạn.Bởi vì các quy tắc căn chỉnh, ba bit dưới cùng là miễn phí; ngoài ra, các hệ thống 64 bit thường có các con trỏ không gian người dùng chỉ với 48 bit quan trọng; phần còn lại là tất cả '1' hoặc' 0', vì vậy bạn có thể đóng một con trỏ vào (53-bit) mantissa của một 'double' với các bit trên của nó được thiết lập để đại diện cho' NaN'. Sau đó, các cờ đặt hàng thấp cho phép bạn nhanh chóng lựa chọn giữa các biểu diễn với mặt nạ và dịch chuyển. –

+0

Nó xuất hiện tôi chỉ cần 6 bit vì vậy tôi thậm chí sẽ không cần 1 hoặc 4k đầu tiên :). Tham chiếu –

Trả lời

4

Không có bảo đảm như vậy. Bạn có thể thử sử dụng placement new nếu bạn cần vị trí bộ nhớ rất cụ thể nhưng có một số sự cố nhất định mà bạn sẽ phải work hard to avoid. Tại sao bạn không thử sử dụng bản đồ có khóa số nguyên có con trỏ làm giá trị thay vì? Bằng cách đó bạn sẽ không phải dựa vào các địa chỉ và phạm vi bộ nhớ cụ thể.

2

Về lý thuyết, không - con trỏ không được đảm bảo là> 0. Tuy nhiên, trong thực tế, được xem như một số nguyên không dấu (đừng quên rằng con trỏ có thể có bit "1" cao), không có hệ thống mà tôi biết sẽ có một giá trị con trỏ ít hơn khoảng 1000. Nhưng dựa vào đó là dựa vào "hành vi không xác định".

+1

? Tôi nghĩ rằng tôi nhớ lại rằng 1GB đầu tiên trong bộ nhớ ảo linux chỉ dành cho hạt nhân, vì vậy nếu đúng, ứng dụng của bạn sẽ không nhận được địa chỉ trong 1GB đầu tiên, trừ khi nó chạy trên chế độ hạt nhân] Tuy nhiên, tôi có thể sai về giả định ban đầu, tôi không thể nhớ nơi tôi nghĩ rằng tôi đọc nó: \ – amit

+0

@amit google-fu của tôi đã đưa ra http://linux-mm.org/HighMemory "3GB cho các chương trình người dùng và 1GB cho hạt nhân" –

+0

@amit - Tôi đã nói rất thường - C++ chạy trên một số hệ thống khá nhỏ. –

1

Không có tiêu chuẩn cho các địa chỉ bộ nhớ hợp lệ đến từ đâu; để viết mã độc lập với hệ thống an toàn, bạn không thể dựa vào một số địa chỉ nhất định (và thậm chí với hỗ trợ giai thoại, bạn không bao giờ biết khi nào sẽ thay đổi với bản cập nhật hệ thống mới).

6

Về mặt chuẩn, không có gì. Nhưng trong thực tế, nó phụ thuộc vào hệ điều hành đích, các cửa sổ ví dụ dự trữ 64kb bộ nhớ đầu tiên là một vùng đất không có (tùy thuộc vào việc xây dựng nó là bộ nhớ chỉ đọc, nếu không nó được đánh dấu là PAGE_NOACCESS), trong khi nó sử dụng trên 0x80000000 + cho bộ nhớ hạt nhân, nhưng nó có thể được thay đổi, xem this & this trên MSDN. Trên x64, bạn cũng có thể sử dụng các bit cao hơn của địa chỉ (chỉ 47bits được sử dụng cho các địa chỉ hiện tại), nhưng nó không phải là một ý tưởng hay, vì sau này nó sẽ thay đổi và chương trình của bạn sẽ bị hỏng. tiêu chuẩn cũng khuyên chống lại nó).

+0

câu trả lời hay nhất +1. –

1

Nó rất nền tảng cụ thể, vì vậy tôi sẽ không khuyến khích dựa vào loại thông tin này trừ khi bạn có một lý do rất tốt và nhận thức được những hậu quả đối với tính di động, khả năng bảo trì, vv

NULL là đảm bảo được 0x0 luôn. Nếu tôi nhớ chính xác, x86 có 128 MB không gian địa chỉ đầu tiên là "NULL-equivalent", để các con trỏ hợp lệ không thể nhận các giá trị trong phạm vi này. Trên x64 có một số additional addresses mà bạn không nên gặp phải trong thực tế, ít nhất là bây giờ.

Đối với không gian địa chỉ dành riêng cho hệ điều hành, nó sẽ phụ thuộc rõ ràng vào hệ điều hành. Trên Linux, bộ phận không gian người dùng hạt nhân được cấu hình trong hạt nhân, vì vậy ít nhất 3 chia tách: 1-3 GB, 2-2 GB và 3-1 GB là phổ biến trên các hệ thống 32 bit. Bạn có thể tìm thêm chi tiết on kerneltrap.

+0

Chắc chắn bạn có nghĩa là 128 * K * B đầu tiên của không gian địa chỉ? –

+0

@CodyGray Không, nó thực sự là 128 MB, không phải kB. Nhưng tôi không hoàn toàn đúng về nguyên nhân. Nó không phải do chính CPU gây ra mà là do cách bố trí không gian địa chỉ của các ứng dụng trên hầu hết các hệ thống giống UNIX. Vùng 0-128 MB được dành riêng cho ngăn xếp, có nghĩa là bạn không nhận được địa chỉ từ phạm vi này khi sử dụng 'new' hoặc' malloc() 'để phân bổ bộ nhớ từ heap. Nó được giải thích rất tốt trong [câu trả lời hay này] (http://stackoverflow.com/a/2187753/1224016). –

Các vấn đề liên quan