【问题标题】:How to find size of elements pointed by array of pointers?如何找到指针数组指向的元素的大小?
【发布时间】:2014-12-21 13:35:38
【问题描述】:

这是代码,

char const *words[] ={
        "Hello",
        "What are you doing",
        0
    };
    int size = sizeof(words[1]), totalSize = sizeof(words);

totalSize 的值是 24,但 size 的值是 8。我使用 gdb 进行运行时查看,因为命令 p words[1] 结果是 $1 = 0x40400f "What are you doing" 所以 words[1] 被调试器视为数组,仍然 sizeof() 将其视为指针。我不明白为什么会这样。

【问题讨论】:

  • words[1] 是指向以空字符结尾的字符串的指针。您(64 位)平台上的指针大小为 8 个字节。调试器向您显示指向字符串的内容这一事实并不意味着编译器引用了words[1]。

标签: c string pointers


【解决方案1】:

调试器向您显示指向字符串的内容这一事实并不意味着编译器将其称为静态分配的数组(可以应用sizeof 运算符“正确”)。

您可以使用这段代码检索这些大小(不包括空字符):

int size = strlen(words[1]);
int totalSize = 0;
for (int i=0; words[i]!=0; i++)
    totalSize += strlen(words[i]);

你也可以去掉 words 数组中的最后一个元素,改用它:

int size = strlen(words[1]);
int totalSize = 0;
for (int i=0; sizeof(words)/sizeof(*words); i++)
    totalSize += strlen(words[i]);

【讨论】:

    【解决方案2】:

    words 是一个由 3 个指向 (const) char 的指针组成的数组。

    所以sizeof 与数组操作数将产生3 个指针的累积大小,而数组元素的sizeof 将产生一个指针的大小。

    【讨论】:

      【解决方案3】:

      这是因为sizeof() 运算符正在被result at compile time 取代。例如,如果在循环中使用,它应该对所有 sizeof(words[i]) 给出相同的结果,对于 sizeof(words[1]) 也是如此。因此编译器将其简单地解释为(64 位)指针。

      【讨论】:

        【解决方案4】:

        words 是一个char 指针数组。因此,它的元素类型是指向char 的指针。 words[1] 是指向 char 的类型指针,而不是 char 的数组,这就是为什么你得到指针的大小而不是它指向的字符串的大小。

        如何找到指针数组指向的元素的大小?

        为了找到指针指向的字符串的大小,你需要循环遍历它。

        int size = 0;
        char const *ptr = words[1];
        while(ptr++) 
            size++;  
        

        或者使用标准库函数strlen

        size_t size = strlen(words[1]);
        

        【讨论】:

        • "...你需要遍历它。" 或者调用strlen()就可以了!
        【解决方案5】:

        你声明了数组words like

        char const *words[]; 
        

        这意味着数组的每个元素都有char const * 类型,sizeof( words[0] ) 相当于sizeof( char const * ),在您的环境中等于 8 个字节。 如果您想知道指针words[0] 指向的字符串字面量的长度,那么您应该使用标头<string.h> 中声明的标准C 函数strlen。例如

        size_t length = strlen( words[0] );
        

        请注意,尽管数组中的所有指针都具有相同的大小,即 8 字节,但这些指针指向的字符串文字具有不同的大小。

        这是一个演示程序

        #include <stdio.h>
        #include <string.h>
        
        int main(void) 
        {
            char const *words[] =
            {
                "Hello",
                "What are you doing",
                0
            };
        
            const char **p = words;
        
            for ( ; *p; ++p ) printf( "\"%s\": %zu\n", *p, strlen( *p ) );
        
            return 0;
        }
        

        输出是

        "Hello": 5
        "What are you doing": 18
        

        字符串文字本身在 C 中也有相应的类型

        char [6] 和 char[19] 因为它们包含终止零。

        【讨论】:

          【解决方案6】:

          初始框显示字符串的基地址。

          +----+    +-----+
          |1000|--->|Hello|
          +----+    +-----+
          words[0]
          
          +----+    +------------------+
          |2000|--->|What are you doing|
          +----+    +------------------+
          words[1]
          

          如果您执行sizeof(words[0]),它是char const* 类型的指针,我们都知道指针的大小对于所有数据类型通常保持不变4,但在您的情况下它是64 位机器和因此你得到8 作为输出。

          出于同样的原因,即使是 sizeof(words[1]) 也会获取您的 8。

          使用指向指针概念的指针来获取该基地址处的字。

          【讨论】:

            猜你喜欢
            • 2018-09-26
            • 2013-01-25
            • 2022-01-02
            • 1970-01-01
            • 1970-01-01
            • 2021-11-28
            相关资源
            最近更新 更多