【问题标题】:problem with sizeof operatorsizeof 运算符的问题
【发布时间】:2011-01-23 07:27:56
【问题描述】:

因为我想在函数中动态查找数组大小,所以我使用了 sizeof 运算符。但我得到了一些意想不到的结果。 这是一个演示程序,向您展示我想要做什么。

//------------------------------------------------------------------------------------------
#include <iostream>

void getSize(int *S1){

    int S_size = sizeof S1/sizeof(int);
    std::cout<<"array size(in function):"<<S_size<<std::endl;
}

int main(){

    int S[]={1,2,3,2,5,6,25,1,6,21,121,36,1,31,1,31,1,661,6};
    getSize(S);
    std::cout<<"array size:"<<sizeof S/sizeof(int)<<std::endl;
    return 0;
}
//------------------------------------------------------------------------------------------

编译命令:g++ demo1.cc -o demo1 {fedora 12}

输出:

array size(in function):2
array size:19

请解释一下,为什么会这样。 有什么办法可以解决这个问题。

【问题讨论】:

  • 阅读this 答案和this 问题。
  • 一个很好的例子说明为什么数组不是指针。

标签: c++ arrays sizeof


【解决方案1】:
void getSize(int *S1)

当你将一个数组传递给这个函数时,它会衰减为指针类型,所以sizeof操作符会返回指针的大小。

但是,您将函数定义为,

template<int N>
void getSize(int (&S1)[N])
{
   //N is the size of array
   int S_size1 = N;
   int S_size2 = sizeof(S1)/sizeof(int); //would be equal to N!!
   std::cout<<"array size(in function):"<<S_size1<<std::endl;
   std::cout<<"array size(in function):"<<S_size2<<std::endl;
}

int S[]={1,2,3,2,5,6,25,1,6,21,121,36,1,31,1,31,1,661,6};
getSize(S); //same as before

那么你可以在函数中获得数组的大小!

在这里亲自观看演示:http://www.ideone.com/iGXNU

【讨论】:

    【解决方案2】:

    getSize() 中,您将获得指针大小,即 8 字节(因为您可能正在运行 64 位操作系统)。在main() 中,您将获得数组的大小。

    如果您想知道数组大小,请将sizeof(S) 的结果作为附加参数传递给getSize()

    更多的选择是使用一些容器(如std::vector)或将函数转换为模板函数,正如 Nawaz 建议的那样。

    【讨论】:

    • 实际上,我想为一场比赛编写一个函数,其中 getSize() 只能接受一个参数。感谢您的建议。:)
    【解决方案3】:

    S 是一个int *,一个指向整数的指针,它是一个内存地址,在您的机器上是整数大小的两倍。

    如果你想要数组的大小(即元素的数量),你不能直接在纯 C 中得到它。但由于这是一个 c++ 问题,有一种方法:使用vector,它有一个size() 方法。

    实际上,这并不完全正确:在函数内 声明 S (并且仅当它在编译时像您在示例中所做的那样显式初始化 - 甚至 new int[19]不起作用),sizeof 运算符实际上确实得到了正确的答案,这就是为什么 c++ 允许您这样做:

    int S[]={1,2,3,2,5,6,25,1,6,21,121,36,1,31,1,31,1,661,6};
    vector<int> v(S, S + sizeof(S) / sizeof(int) );
    

    然后你可以使用v.size()(见these docs)。

    Nawaz 其他地方的模板版本是另一个很好的建议,它强制编译器携带有关 c++ 数组构造的完整信息(再次注意,这在编译时都是已知的,这就是为什么你可以在参数中明确说明大小)。

    【讨论】:

      【解决方案4】:

      您正在获取指向数组的指针的大小。如果你想要数组的大小,你必须将元素的数量乘以每个元素的大小。

      【讨论】:

        【解决方案5】:

        您必须将数组的大小传递给函数。

        由于您只传递了指向数组中第一个元素的指针,因此您的函数没有关于其实际大小的信息。

        void getSize(int *S1, size_t size)
        {
            int S_Size = sizeof(*S1) * size;
        }
        

        如果您考虑一下,这是多余的:D

        【讨论】:

          【解决方案6】:

          为防止这种类型的 sizeof 意外误用,您可以定义一个仅适用于数组的函数:

          template<class T, int N>
          int array_size(T (&)[N]) {
            return N;
          }
          

          如果您在代码中使用它,当应用于 S1 时,您会看到编译器错误,因为它不是数组。另外,它比 sizeof array / sizeof array[0] 更短且更明确(使用第一项的大小意味着您不必重复数组类型)。

          这也已经以更一般的形式存在于 Boost 中(接受任何带有大小方法的东西,例如 std::vector)。

          【讨论】:

            猜你喜欢
            • 2012-09-17
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-03-25
            • 2015-03-04
            • 2016-03-29
            • 1970-01-01
            相关资源
            最近更新 更多