2012-05-17 62 views
7

我有一个缓冲区,并想做一个测试,看看缓冲区是否有足够的容量I.e.找到我可以添加到缓冲区的元素的数量。如何确定分配的C缓冲区的大小?

char *buffer = (char *)malloc(sizeof(char) * 10); 

做一个

int numElements = sizeof(buffer); 

不返回10,我如何能做到这一点任何想法?

回答

3

buffer只是一个没有尺寸信息的指针。然而,malloc()例程将保存你所做的分配的大小,所以当你释放()它时,它会释放适量的空间。所以除非你想在malloc()函数中潜水,否则我建议你自己保存分配的大小。 (对于可能的实现,请参阅其他API答案中的示例)。

11

你不能做这样的测试。记住你分配了多少内存是你自己的责任。如果缓冲区是由其他人提供的,则要求他们也传递大小信息,并使其负责传递正确的值或使程序死亡。

6

由于buffer是一个指针(不是数组),所以sizeof运算符返回指针的大小,而不是它指向的缓冲区的大小。还有就是要确定这个尺寸的标准方法,所以你必须做簿记自己(即记住你分配多少。)

顺便说一句,它是

char *p = "hello, world\n"; /* sizeof p is not 13. */ 

有趣的是一样的,

sizeof "hello, world\n" 

是14.你能猜出原因吗?

+12

你真的把问题传回提问者吗?这不是真正的原因... – Evert

+0

@Jens嗯,我知道sizeof()返回字符串文字和数组的正确大小,但为什么?尺寸信息存储在哪里?例如char * p =“hello”给出了指针的大小,char p [10]给出十个大小。 – Zebrafish

+0

@Evert我们在这里得到答案,他给出了答案。提出跟进问题是一种合法的教育手段。此外,我不认为他的问题值得批评,因为他的问题的答案是他刚才给出的答案,所以他没有真正隐藏信息。我想人们可以辩论为“读者练习”等等的功效或价值,但在这种情况下,它非常简洁和相关。 –

0
struct buffer 
{ 
    void 
    *memory 

    size_t 
    length; 
}; 

void *buffer_allocate(struct buffer *b, size_t length) 
{ 
    assert(b != NULL); 

    b->memory = malloc(length) 
    b->length = length; 

     // TRD : NULL on malloc() fail 
     return(b->memory); 
} 

int buffer_valid(struct buffer *b, size_t length) 
{ 
    assert(b != NULL); 

    if(b->memory == NULL or length > b->length) 
    return(0); 

    return(1); 
} 

void *buffer_get(struct buffer *b) 
{ 
    assert(b != NULL); 

    return(b->memory); 
} 

使用API​​而不是malloc/free,您不会出错。

+0

如果你真的想要聪明,你可以编写自己的'malloc'来使用系统'malloc'来分配四个额外的字节,存储分配的长度并在这个长度之后返回一个指针。然后你可以有一个'getSize'方法,它使用指针算术来再次抓住它。它可以让你使用看起来像'malloc'和'free'的调用。 –

+0

我不确定这很聪明 - 这意味着您的个人malloc现在与其他所有人的行为不同。我认为调整核心职能行为是有风险的。它支撑了一切。 – 2012-05-17 17:00:10

+1

我认识一家公司,重复使用malloc,以便将它分配的所有内容放到freelist中,然后free将这个元素返回给freelist。令人惊叹的是,它的功能以及它的实现方式(并不令人惊讶,因为这个想法有多糟糕),而且如此深入地嵌入代码中,它永远不会被删除。 – 2012-05-17 17:01:09

0

sizeof用于计算实际对象的大小,而不是内存中对象的指针。它返回结构或原语的大小。我的意思是它会工作,但会给你指针的大小,而不是它指向的结构。为了获得任何种类的阵列中使用的长度:

的strlen(缓冲液)

+0

使用strlen()仅适用于字符串(即以NUL字节结尾)。一般来说,你不能指望'strlen'给你“任何数组的长度”。事实上,它是相反的:'sizeof' ** does **会给你任何类型数组的大小。 – Jens

+0

所以,正确的方法是:sizeof(* buffer)? – SpaceBear

+0

不,由于声明是'char * buffer',所以'sizeof * buffer'是'sizeof char',它是1.除了记住你如何调用malloc/calloc之外,没有办法确定动态分配的缓冲区的大小/ realloc的。但对于声明为'char foo [N]'的**数组','sizeof foo'是'N'。 – Jens

19

对于GNU的glibc:

SYNOPSIS 

#include <malloc.h> 
size_t malloc_usable_size (void *ptr); 

说明

的malloc_usable_size()函数返回由ptr指向的块中的可用字节数,指向由malloc(3)分配的内存块的指针或一个相关的功能。

+0

注意:这可能会导致严重的开销,因为它取决于malloc实现。并且它返回分配的字节。要获得可用元素的数量,您需要额外的部门。该人清楚地说:“由于对齐和最小大小限制,malloc_usable_size()返回的值可能会大于请求的分配大小。虽然超出的字节可以被应用程序覆盖而没有不良影响,但这并不好编程实践**:分配中多余的字节数取决于底层实现。“ – Stargateur