2010-05-04 54 views
2

我想出了這個作爲調試問題的快速解決方案 - 我有指針變量和它的類型,我知道它指向堆上分配的對象數組,但我不知道有多少。所以我寫了這個函數來查看存儲內存分配到堆時的字節數的cookie。看看C++新的[] cookie。這個代碼是多麼便攜?

template< typename T > 
int num_allocated_items(T *p) 
{ 
return *((int*)p-4)/sizeof(T); 
} 

//test 
#include <iostream> 
int main(int argc, char *argv[]) 
{ 
    using std::cout; using std::endl; 
    typedef long double testtype; 
    testtype *p = new testtype[ 45 ]; 

    //prints 45 
    std::cout<<"num allocated = "<<num_allocated_items<testtype>(p)<<std::endl; 
    delete[] p; 
    return 0; 
} 

我想知道這個代碼的便攜性。

回答

11

它甚至不是可移動的。

一個實現可以執行堆簿記,但它想要的並且絕對沒有辦法可移植地獲得堆分配的大小,除非你自己跟蹤它(這是你應該做的)。

+0

正如我懷疑。乾杯。舊版代碼 – Carl 2010-05-04 00:57:45

2

不能攜帶。但爲什麼不使用std::vector?然後你可以直接詢問它包含了多少元素,並且你不需要擔心內存管理和異常安全。

+0

。這就是爲什麼:) – Carl 2010-05-04 02:36:21

2

您可以全局重載array上的new/delete操作符,並將大小放入內存區域。你得到一個便攜式解決方案

下面的代碼演示瞭如何:

void * operator new [] (size_t size) 
{ 
    void* p = malloc(size+sizeof(int)); 
    *(int*)p = size; 
    return (void*)((int*)p+1); 
} 

void operator delete [] (void * p) 
{ 
    p = (void*)((int*)p-1); 
    free(p); 
} 

template<typename T> 
int get_array_size(T* p) 
{ 
    return *((int*)p-1)/sizeof(T); 
} 


int main(int argc, char* argv[]) 
{ 
    int* a = new int[200]; 
    printf("size of a is %d.\n", get_array_size(a)); 
    delete[] a; 
    return 0; 
} 

結果:

size of a is 200. 
+0

只是想知道這一點。乾杯。 – Carl 2010-05-04 03:15:29

+0

他說這個數組是分配在堆上的,而不是它通過'new []'分配的。 – 2010-05-04 03:16:27

+0

@carleeto:爲了澄清我的評論,因爲這似乎是你正在考慮的事情,在一般情況下,你無法知道指針是如何分配的。除了直接通過'malloc'分配數組的可能性之外,類可以單獨覆蓋'operator new []'。在這種情況下,舍伍德的「get_array_size」並不比你自己的可靠。 – 2010-05-04 04:55:09