开发者

static array in c++ forgets its size

开发者 https://www.devze.com 2022-12-28 15:02 出处:网络
In this small example, c++ forgets size of an array, passed to a constructor. I guess it is something simple, but I cannot see it.

In this small example, c++ forgets size of an array, passed to a constructor. I guess it is something simple, but I cannot see it.

In classes.h, there is this code:

#ifndef CLASSES_INC
#define CLASSES_INC
#include <iostream>

class static_class {
 public:
 static_class(int array[]) {
  std::cout<<sizeof(array)/sizeof(int)<<"\n";
 } 
};

class my_class{
 public:
 static static_class s;
 static int array[4];
};

#e开发者_如何学Pythonndif

In classes.cpp, there is this code:

#include "classes.h"

int my_class::array[4]={1, 2, 3, 4}; 

static_class my_class::s = static_class(my_class::array);

In main.cpp, there is only simple

#include "classes.h"

int main () {

 return 0;
}

Now, the desired output (from the constructor of static_class) is 4. But what I get is 1. Why is that?

edit:

A lot of answers suggest that sizeof on pointer returns the size of a pointer. That is not true, AFAIK (from http://msdn.microsoft.com/en-us/library/4s7x1k91(VS.71).aspx - "When the sizeof operator is applied to an array, it yields the total number of bytes in that array, not the size of the pointer represented by the array identifier.")

edit2:

ok, as I found out, when compiler can see the size, sizeof returns the whole size, but when it decays to a pointer (which is the case here), sizeof actually really returns size of pointer.


When declaring a function parameter, the following two are equivalent because an array decays to a pointer when it is passed as an argument:

int array[]
int *array;

So, you end up computing sizeof(int*) / sizeof(int), which happens to be one on your platform because their sizes are the same.

If you need the size of the array in your function, you should pass it as an argument to the function, or use a container that keeps track of the size for you.


There's also a template option, something like this?

class static_class
{
public:
   template<int I>
   static_class(int (&array)[I])
   {
      std::cout << I << std::endl;
   } 
};

I think that'd work, anyway. sizeof(array)/sizeof(array[0]) only works in scopes where the array's definition is actually visible. In other words, your static_class constructor couldn't "see" the size of the array, all it knew was that it was getting an array of some (any) size. You could pass an array of 100 elements or four, and the function itself would get no information.

In my example, on the other hand, the template will cause one version of the function to be created for each array size that you pass in. This may or may not be desirable. Generally speaking, it's best to keep the array size somewhere handy, like:

class my_class
{
public:
   static static_class s;
   static const int array_size = 4;
   static int array[array_size];
};

Then you can pass my_class::array_size around and not have to be worried about what the compiler may or may not have visible regarding array attributes.


In C, and therefore I presume in C++, any array that's passed through as a parameter is turned into a simple pointer type, which loses the size information. Since your static_class constructor gets the array from a parameter, it loses its array quality.


The basic problem that the other answers hint at is that arrays are not first class types in C/C++. In particular, you cannot declare functions or function types that take arrays as arguments. Now, for historical reasons lost in the depth of time, instead of just saying that declaring a function argument that is an array is an error, it was decided that the compiler should silently turn the array declaration into a pointer declaration. This has lead to no end of confusion with people declaring arrays as arguments and unexpectedly getting pointers instead.


becuase array is a pointer at the point where you do sizeof(array). The array never knew its size (see what happens if you try to access an element beyond its end). The compiler knew at the point where it was defined; that all

Anyway the solution you want is std::vector


You'd be surprised, but in C++, arrays are just pointers, nothing more. The array size is not stored anywhere, and certainly it not possible to pass function arguments of variable size.

0

精彩评论

暂无评论...
验证码 换一张
取 消