2009-03-04 192 views
11

我已经将缓冲区设置为大小100. 我在声明缓冲区的主函数中显示缓冲区。但是,当我将缓冲区传递给函数并获取sizeof'4'时,我认为它应该是100,因为这是我在主要版本中创建的缓冲区的大小。 输出: 缓冲区大小:100 的sizeof(缓冲液):4将char缓冲区传递给函数并获取缓冲区的大小

#include <string.h> 
#include <stdio.h> 

void load_buffer(char *buffer); 

int main() 
{ 
    char buffer[100]; 
    printf("buffer size: %d\n", sizeof(buffer)); 
    load_buffer(buffer); 

    return 0; 
} 

void load_buffer(char *buffer) 
{ 
    printf("sizeof(buffer): %d\n", sizeof(buffer)); 
} 
+2

在main()中显式声明了一个数组,而在load_buffer()中声明了一个指针。不同之处在于,在main()中,编译器知道缓冲区是一个数组,但是在load_buffer()中,编译器不知道缓冲区是来自数组,还是堆中分配的内存和结构或其他。编译器只知道内存地址(因此是一个指针),所以sizeof()返回内存地址的大小,它的长度是4个字节(因为它是一个32位的机器,如果它是一个64位的机器,它将是8字节长)。希望这有助于理解更多。 – AndaluZ 2014-04-01 12:15:53

+0

而不是sizeof()函数,使用strlen(),然后它返回指针值的大小。 – NandhaKumar 2018-01-05 06:18:47

回答

19

您正在使用指针的大小到缓冲区(4个字节),而不是缓冲区的大小。

在C中,您必须分别传递缓冲区的大小,这是缓冲区溢出发生的原因之一。

void load_buffer(char * buffer, size_t bufSize) 
{  
    ... 
} 
4

会发生什么事,就是当你传递一个数组给一个函数,你只能通过数组的地址在内存中,数组的不是大小。在load_buffer()中输出的sizeof(buffer)是指针的大小,它是四个字节。

保持功能的缓冲区的大小,最好的办法是改变功能:

void load_buffer(char *buffer, int length); 

和调用:

load_buffer(buffer, sizeof(buffer)); 

,然后使用长度,每当你想缓冲区的大小。

8

从OP

void load_buffer(char *buffer) 
{ 
    printf("sizeof(buffer): %d\n", sizeof(buffer)); 
} 

即使你可以想象load_buffer()是通过buffer通过refrence,究竟发生什么事是你被值指针传递到char实际的数组没有通过所以load_buffer()函数没有办法知道缓冲区的大小

那么sizeof(buffer)在做什么?它只是返回一个指向char的指针的大小。如果load_buffer()需要buffer的大小,则需要通过快速传递。

或对结构相反,您可以创建包含一个字符数组,数组的大小的新结构,并通过一个指针,这样的缓冲和它的大小永远在一起;)

20

的Mitch Wheat和hhafez的答案完全正确并且重要。我将展示一些有时可能有用的附加信息。

请注意,如果你告诉编译器,你有合适的尺寸

void load_buffer(char buffer[100]) { 
    /* prints 4 too! */ 
    printf("sizeof(buffer): %d\n", sizeof(buffer)); 
} 

为参数数组只是声明一个指针数组同样的情况。即使它被声明为char name[N],编译器也会自动将其更改为char *name

如果要强制调用者只传递大小为100的数组,可以接受的阵列,而不是地址(以及该类型):

void load_buffer(char (*buffer)[100]) { 
    /* prints 100 */ 
    printf("sizeof(buffer): %d\n", sizeof(*buffer)); 
} 

这是一个指向数组你有主,所以你需要在函数中取消引用来获取数组。索引然后被

buffer[0][N] or (*buffer)[N] 

没有人知道我是这样做,我也不做我自己做的,因为它比较复杂的论证通过。但知道这件事很好。您可以调用函数这样便

load_buffer(&buffer) 

如果你想接受其他尺寸太大,我会与过去的-N选择其他两个答案建议去。