12

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

#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));
}
4

4 回答 4

24

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

在 C 中,您必须单独传递缓冲区的大小,这是缓冲区溢出如此容易和频繁发生的部分原因。

void load_buffer(char * buffer, size_t bufSize)
{    
    ...
}
于 2009-03-04T04:52:19.787 回答
23

Mitch Wheat 和 hhafez 的回答是完全正确和中肯的。我将展示一些有时可能有用的附加信息。

请注意,如果您告诉编译器您有一个大小正确的数组,也会发生同样的情况

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

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

如果你想强制调用者只传递一个大小为 100 的数组,你可以接受数组的地址(以及它的类型):

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

它是指向您在 main 中的数组的指针,因此您需要在函数中取消引用以获取数组。然后索引由

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

我认识的人都没有这样做,我自己也没有这样做,因为这会使争论的传递变得复杂。但很高兴知道它。然后你可以像这样调用函数

load_buffer(&buffer)

如果您也想接受其他尺寸,我会选择其他两个答案推荐的 pass-N 选项。

于 2009-03-04T05:11:58.023 回答
8

来自 OP

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

即使您可以想象它load_buffer()buffer按引用传递的,但真正发生的是您传递的是char值传递的指针。实际数组未传递,因此load_buffer()函数无法知道缓冲区数组的大小

那么在sizeof(buffer)做什么呢?它只是返回指向 char 的指针的大小。如果load_buffer()需要它的大小,buffer则需要单独传递。

或者您可以创建一个包含 char 数组和数组大小的新结构,然后将指针传递给该结构,这样缓冲区和它的大小总是在一起;)

于 2009-03-04T04:57:17.387 回答
4

发生的情况是,当您将数组传递给函数时,您只传递了数组在内存中的地址,而不是数组的大小。load_buffer() 中输出的 sizeof(buffer) 是指针的大小,即四个字节。

保持函数中缓冲区大小的最佳方法是将函数更改为:

void load_buffer(char *buffer, int length);

并呼吁:

load_buffer(buffer, sizeof(buffer));

然后在需要缓冲区大小时使用长度。

于 2009-03-04T04:56:01.070 回答