首页 文章

sizeof()和strlen()之间的区别[重复]

提问于
浏览
-2

这个问题在这里已有答案:

我有一个看起来像这样的功能:

void functionname(int a, char* c){
sprintf(c, " ... some text ...");
}

上面的语句使用sprintf写入'c'数组 .

对于我的系统,我不认为我可以使用sprint,因为我使用的是不同的(嵌入式)操作系统 .

打印功能我使用的东西看起来像snprintf,我想知道如何使这个功能与snprintf一起使用 .

我是否使用strlen(c)?当c为空时会发生什么?,我使用sizeof(c)吗?

snprintf(c, sizeof(c), " ... text");

要么

snprintf(c, strlen(c), "... text");

调用'functionname'的函数有一个数组,它将c的长度定义为c [64] . 我担心调用sizeof(c)会导致指针的大小 . 还担心当数组不包含字符串时strlen将导致返回0 .

所以问题是如何告诉snprintf达到c [64]的这个值 .

如何获得指针c指向的数组的大小,并将此答案放在snprintf函数中 . 如果有一种方法可以从sprintf()到snprintf()使用相同的变量,那么可以提供给sprintf()?在sprint()函数以char指针为目标的情况下?

5 回答

  • 1

    除了几个例外, sizeof 是编译时可评估的,并为您提供类型的大小 . 因此,它无法知道运行时间的事情,比如"string"的长度 .

    strlenconst char* 上运行,并沿着内存从起始指针跟踪,直到达到第一个 \0 ,然后返回它所产生的进度数 . 's convenient since it can be used to compute the length of a 1072277 , assuming it'被建模为一系列以零字节终止的非零字节 .

  • 1

    在这段代码中:

    void functionname(int a, char* c){
        sprintf(c, " ... some text ...");
    }
    

    c 仅仅是一个指针,而不是一个数组 . 所以 sizeof(c) 将是 sizeof(char *) ,即2,4或8,具体取决于体系结构(分别为16,32或64位) .

    strlen(c) 仅在 c 开始的内存中给出第一个空位置 . 如果调用者将数组初始化为0,那么它将只是... 0

    所以这里都不能使用 . 最好的方法是让调用者传递数组的实际大小,并对被调用者有信心:

    void functionname(int a, char* c, size_t size){
        snprintf(c, size, " ... some text ...");
    }
    
  • 1

    我如何获得指针c指向的数组的大小,

    你不能 .

    代码需要跟踪指针指向的有效内存量 .

    指针不保存它指向的有效存储器大小的信息,而只保存存储区的地址,甚至可能是0的大小 .

  • 0

    http://linux.die.net/man/3/snprintf声明snprintf中的size参数包含将要写入的最大字符数;这是一种防止写入超出c的任何存储开始的保护 . (顺便说一句, c ?为什么不 s ?) .

    snprintf 无法找到最大值 . 目的地的可用内存大小应该从分配时(动态或通过数组定义)得知 .

    编辑:在一般情况下,必须将 c 处可用的字节数作为参数传递给 functionname (出于同样的原因,必须将其传递给 snprintf ) . 如果函数可以共享(例如通过标头)数组大小的#define,或者可以访问包含内存大小的全局变量,那么这可能不是必需的.--

    这就是说:如果你确定c的内存足够,或者如果你进入不安全的程序,你当然可以将一些大数字传递给 snprintf . 只要内存确实足以用于在运行时写入的文本,这将起作用 . snprintfsize 参数只是将上限传递给 snprintf ,这将在运行时触及超出其需要触摸的内存 .

  • 1

    由于 c 是指针, sizeof(c) 将返回指针的大小,这取决于平台的体系结构,例如32位 - > 4,16位 - > 2 .

    strlen(c) 也不会帮助你,因为它通过停在第一个空字符来计算字符串的长度 .
    如果您的缓冲区未初始化,则不会比未定义的行为更好 .

    您需要知道 c 引用的缓冲区的实际大小 .

    缓冲区可以静态分配在堆栈上,如下所示:

    char buffer[250];
    char * c = buffer;
    

    或动态:

    int sz = 250;
    char * buffer = malloc(sz * sizeof(char));
    char * c = buffer;
    

    您需要知道它的实际大小(此处为250),将其明确地传递给调用sprintf变体的函数:

    void functionname(int a, char* c, int sz){
        snprintf(c, sz, " ... some text ...");
    }
    

    我在这里假设 a 是一个完全不相关的变量 .

相关问题