将 char 缓冲区传递给函数并获取缓冲区的大小

Posted

技术标签:

【中文标题】将 char 缓冲区传递给函数并获取缓冲区的大小【英文标题】:passing char buffer to functions and getting the size of the buffer 【发布时间】:2010-10-11 04:34:30 【问题描述】:

我已将缓冲区大小设置为 100。 我在声明缓冲区的主函数中显示缓冲区。 但是,当我将缓冲区传递给函数并获得 sizeof '4' 时, 我在想它应该是 100,因为那是我的缓冲区的大小 在main中创建。 输出: 缓冲区大小:100 大小(缓冲区):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));

【问题讨论】:

在 main() 中显式声明了一个数组,而在 load_buffer() 中声明了一个指针。不同之处在于,在 main() 中,编译器知道 buffer 是一个数组,但在 load_buffer() 中,编译器不知道 buffer 是来自数组,还是堆中分配的内存空间,还是结构或其他任何东西.编译器只知道内存地址(因此是指针),所以 sizeof() 返回内存地址的大小,长度为 4 个字节(因为它是 32 位机器,如果是 64 位机器,则为 8字节长)。希望这有助于理解更多。 用strlen()代替sizeof()函数,然后返回指针值的大小。 【参考方案1】:

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

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

void load_buffer(char * buffer, size_t bufSize)
    
    ...

【讨论】:

【参考方案2】:

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));

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

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

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

load_buffer(&buffer)

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

【讨论】:

【参考方案3】:

来自 OP

void load_buffer(char *buffer)

    printf("sizeof(buffer): %d\n", sizeof(buffer));

尽管您可以想象 load_buffer() 通过引用传递给 buffer,但真正发生的是您通过 value 传递指向 char 的指针。 实际数组不是已通过,因此load_buffer() 函数无法知道缓冲区数组的大小

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

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

【讨论】:

【参考方案4】:

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

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

void load_buffer(char *buffer, int length);

以及调用:

load_buffer(buffer, sizeof(buffer));

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

【讨论】:

以上是关于将 char 缓冲区传递给函数并获取缓冲区的大小的主要内容,如果未能解决你的问题,请参考以下文章

指针类型转换:对缓冲区长度的影响?

检查指针是不是已分配内存

在 C++ 中通过引用传递 char 的效率

刷新缓存区方式和刷新内存到磁盘方式总结。

C++ 中的高效循环缓冲区,将传递给 C 风格的数组函数参数

驱动模块传参数-9