2010-10-14 41 views
7

thể trùng lặp:
pointer to a specific fixed addressLàm thế nào để khởi tạo một con trỏ đến một địa chỉ bộ nhớ cụ thể trong C++

Một cuộc thảo luận thú vị về vấn đề này bắt đầu here nhưng không ai đã có thể cung cấp cho C++ cách làm:

#include <stdio.h> 

int main(void) 
{ 
    int* address = (int *)0x604769; 
    printf("Memory address is: 0x%p\n", address); 

    *address = 0xdead; 
    printf("Content of the address is: 0x%p\n", *address); 

    return 0; 
} 

Cách thích hợp nhất của làm một điều như vậy trong C++?

+3

Ngoài việc thay đổi thành cấu trúc C++, không có sự khác biệt thực sự với cách bạn thực hiện trong C++. – CashCow

Trả lời

18

Trong C++, luôn luôn thích reinterpret_cast trên một C-cast. Nó quá xấu xí đến nỗi ai đó sẽ ngay lập tức phát hiện ra mối nguy hiểm.

Ví dụ:

int* ptr = reinterpret_cast<int*>(0x12345678); 

Đó là điều đau mắt tôi, và tôi thích nó.

+1

Mã mẫu là trong C và OP biết nó là. Anh ta hỏi liệu có cách nào tốt hơn để làm tương tự trong C++ không. Trong trình điều khiển thiết bị, bạn cũng có thể biết địa chỉ tuyệt đối mà bạn muốn ghi vào. Tôi nhớ đã làm điều này trong những ngày đầu với MS-DOS để viết trực tiếp vào màn hình bộ nhớ. Với các macro - tất nhiên. – CashCow

+2

Truy cập thanh ghi phần cứng thông qua địa chỉ là thực tế phổ biến trong các hệ thống nhúng. Chúng được định nghĩa là con trỏ liên tục hoặc được khai báo bằng '# define'. –

+1

Tại sao bạn lại đi đến 'void *'? Mã OP muốn một con trỏ đến một 'int' –

1

Không có cách nào tiêu chuẩn và di động để làm như vậy. Các cách không di động có thể bao gồm reinterpret_cast (someIntRepresentingTheAddress).

0

này sẽ làm việc:

void *address=(void *) 0xdead; // But as mentioned, it's non-standard 

address=(void *) 0xdeadbeef; // Some other address 
+1

Nếu câu hỏi là "cách C++" thì bạn lấy một tình huống xấu và làm cho nó tồi tệ hơn bằng cách đi với 'void *' –

0

Trong C++, tôi thích để khai báo con trỏ như con trỏ liên tục trong một tập tin tiêu đề:

volatile uint8_t * const UART_STATUS_REGISTER = (uint8_t *) 0xFFFF4000; 

Trong ngôn ngữ C, điều này thường được thực hiện sử dụng một macro:

#define UART_STATUS_REGISTER ((volatile uint8_t * const) 0xFFFF4000) 

Trong phần còn lại của mã nguồn, địa chỉ bộ nhớ được tham chiếu qua tên tượng trưng.

1

Tôi muốn nói thêm rằng bạn có thể gọi tổng đài vị trí cho mới nếu bạn muốn có một constructor đối tượng gọi khi gán cho nó tại địa chỉ được chỉ định:

int *pLoc = reinterpret_cast<int*>(0x604769); 
int *address = new (pLoc) int (1234); // init to a value 

này cũng được sử dụng cho các đối tượng bộ nhớ cache. Tạo một bộ đệm và sau đó gán một đối tượng cho nó.

unsigned char *pBuf = new unsigned char[sizeof(CMyObject) + alignment_size]; 
allign_buf(pBuf); 
CMyObject *pMyObj = new (pBuf) CMyObject; 
Các vấn đề liên quan