2010-07-31 27 views
6

Tôi đang cố gắng thực hiện một trình quản lý bộ nhớ tùy chỉnh và tôi tự hỏi nếu có cách nào tốt hơn để thực hiện chức năng này, như khi tôi được hỏi về số học con trỏ void, nhiều người nghĩ rằng nếu tôi có một khoảng trống * trong C++, một cái gì đó rất sai.Custom Memory Manager

// allocates a page of memory. 
void ObjectAllocator::allocatePage() 
{  
    //if(OAStats_.PagesInUse_ >= Config_.MaxPages_) 
     //throw exception 

    void* buffer = ::operator new(OAStats_.PageSize_); // allocate memory, no constructor call. 

    // =============== Setup the PageList_ =============== 
    GenericObject* pNewNode = ::new(buffer) GenericObject(); // Construct GenericObject for the pagelist. 
    pNewNode->Next = PageList_->Next;       // pNewNode points to wherever PageList_ pointed to. 
    PageList_->Next = pNewNode;         // PageList_ points to pNewNode 
    pNewNode = NULL;           // dont need this handle anymore 
    buffer = static_cast<char*>(buffer) + sizeof(GenericObject); // move pointer to point after the generic object. 

    // =============== Setup the FreeList_ =============== 
    for(int i=0;i<Config_.ObjectsPerPage_;++i) 
    { 
     static GenericObject* pPreviousNode = NULL;   // static variable to hold the previous node 
     pNewNode = ::new(buffer) GenericObject();   // Construct GenericObject for the freelist. 
     pNewNode->Next = pPreviousNode; 
     pPreviousNode = pNewNode; 
     buffer = static_cast<char*>(buffer) + OAStats_.ObjectSize_; // move pointer by ObjectSize. 
     ++OAStats_.FreeObjects_; 
    } 
    FreeList_->Next = pNewNode; 

    ++OAStats_.PagesInUse_; 
    ++OAStats_.Allocations_; 
} 
+2

"một số người nghĩ rằng nếu tôi có khoảng trống * trong C++, có điều gì đó rất sai." <- Tôi sẽ không đồng ý với điều đó. Void con trỏ có sử dụng của họ. Tôi cho rằng nó đi xuống cho dù bạn là một phần của cộng đồng 'chống C' C++, hay không. Tôi có xu hướng nói rằng trong khi có, C++ là một ngôn ngữ cấp cao hơn C, mọi người thường làm những điều cấp thấp trong đó và do đó không có gì sai khi sử dụng nhiều tính năng 'C-like' hơn. – Stephen

+2

@Stephen: Tại sao có quá nhiều lập trình viên có phản xạ đầu gối này khi một khái niệm bị chỉ trích họ chỉ * có * để nói "nó không phải là xấu, nó có sử dụng của nó". Tôi cho rằng bạn nói giống nhau về những người độc thân và gotos. Nhưng trong trường hợp này, việc sử dụng void là gì? Tại sao anh ta nên sử dụng một khoảng trống * ở đây? – jalf

+1

@Jalf Bởi vì những nhận xét tiêu cực dính vào tâm trí của mọi người nhiều hơn những bình luận tích cực. Điều đó có nghĩa là nếu một người mới lập trình, hoặc chưa từng nghe về X trước đây, hãy đọc một bình luận cho rằng X sẽ nói rằng bạn không nên sử dụng nó, họ có khả năng nắm lấy kiến ​​thức đó và đánh giá nó như một thực tế trong tâm trí họ. Moreso, tôi chỉ đang nói một ý kiến. Bạn có trả lời tương tự nếu tôi đã sao lưu chế độ xem "không sử dụng con trỏ void" không? Ở đây không, không có lý do để sử dụng nó, nhưng OP chỉ đơn giản nói rằng mọi người đã nói với anh ta không sử dụng chúng nói chung khi mã hóa C++. – Stephen

Trả lời

7

Nếu bạn cần một khối bộ nhớ để lưu trữ chuỗi (8-bit ANSI), bạn nên khai báo một con trỏ tới bộ đệm đó là char và thao tác trên nó.

Trong trường hợp của bạn, bạn cần một khối bộ nhớ là 'blob', nó không có kiểu cố hữu, vì vậy bạn đã chọn đúng void * để biểu thị đốm màu đó.

Bây giờ bạn cần phải tăng con trỏ đó bằng kích thước của một số đối tượng. Bạn không thể thực hiện số học trên một con trỏ void vì lý do rõ ràng, vì vậy bạn làm gì? Bỏ nó. Không có gì phải xấu hổ.

5

Trong C++, trên byte thô, hãy sử dụng char * và không nghĩ đến bất kỳ phần nào của chính bạn. Đó là điều phải làm (tm). Đặc biệt là nếu bạn quấn nó trong một cấu trúc cấp cao hơn, giống như bạn có.

+0

Tại sao lưu ý, ẩn danh? Giải thích và tôi sẽ sửa lại –

2

Không có gì sai với khoảng trống *. Tuy nhiên, những gì chúng ta thường thấy là những người đến từ C, người sử dụng quá mức nếu họ làm điều gì khác. Nếu bạn đang quản lý blob bộ nhớ nguyên, thì khoảng trống * là hoàn toàn phù hợp. Tuy nhiên, hiếm khi có bất kỳ lý do nào khác để làm điều đó.

+0

+1. Không quan tâm, cách điển hình để 'lạm dụng void *' là gì? – JBRWilkinson

+0

void * dữ liệu, kích thước int; memcpy (dữ liệu, bộ đệm, kích thước); thay vì sử dụng template và copy constructor. – Puppy