Why Use Array Size 1 Instead of Pointer

Why use array size 1 instead of pointer?

With this, you don't have to allocate the memory elsewhere and make the pointer point to that.

  • No extra memory management
  • Accesses to the memory will hit the memory cache (much) more likely

The trick is to allocate more memory than sizeof (SomeClass), and make a SomeClass* point to it. Then the initial memory will be used by your SomeClass object, and the remaining memory can be used by the data. That is, you can say p->data[0] but also p->data[1] and so on up until you hit the end of memory you allocated.

Points can be made that this use results in undefined behavior though, because you declared your array to only have one element, but access it as if it contained more. But real compilers do allow this with the expected meaning because C++ has no alternative syntax to formulate these means (C99 has, it's called "flexible array member" there).

Array of size 1 vs. pointer to struct

The answer is yes, they are effectively the same. First, arrays are passed as pointer to its first element, when used in function arguments. Actually, all objects in C can be treated as a array of one element of that type in terms of storage.

Why does it say the length of the array is 1 in this function (C++)?

The function parameter has a pointer type

int len(int *thing) {
return sizeof(thing) / sizeof(int);
}

Even if you will rewrite the function like

int len(int thing[]) {
return sizeof(thing) / sizeof(int);
}

nevertheless the compiler will adjust the array type of the function parameter to the type pointer to the array element type as written in the first function declaration.

So within the function the expression sizeof(thing) yields the size of a pointer. If the size of a pointer is equal to the value of sizeof( int ) then the function returns 1.

You could write instead

template <size_t N>
size_t len(const int ( &thing )[N] ) {
return N;
}

and then

cout << len(fard);

to get the number of elements in the array fard.

Pay attention to that there is already standard C++ function std::size declared in the header <iterator> in C++ 17.

So you could write

#include <iterator>

//...

std::cout << std::size(fard);

why do I see different values of array size in main vs other function

As you can see from the function declaration

void print(int *a)
{
cout<<sizeof(a);
}

the function deals with a pointer. So this statement

cout<<sizeof(a);

outputs the size of the pointer that is equal either 4 or 8 bytes depending on the used system.

Pay attention to that even if you will declare the function like

void print(int a[])
{
cout<<sizeof(a);
}

you will get the same result because the parameter is implicitly adjusted by the compiler to the type int *.

That is the previous and this function declarations are equivalent.

If you want that the function would deal with the original array instead of a pointer that points to the first element of the passed array as an argument then declare the function at least like.

void print( int ( &a )[10] )
{
cout<<sizeof(a);
}

That is declare the parameter as a reference.

Or you can make the function a template function like

template <size_t N>
void print( int ( &a )[N] )
{
cout<<sizeof(a);
}

As the passed array is not being changed in the function then the parameter should have the qualifier const

template <size_t N>
void print( const int ( &a )[N] )
{
cout<<sizeof(a);
}

Here is a demonstrative program.

#include <iostream>

template <size_t N>
void print( const int ( &a )[N] )
{
std::cout << sizeof( a ) << '\n';
}

int main()
{
int arr[10];

std::cout << sizeof( arr ) << '\n';

print( arr );

return 0;
}

Its output is

40
40

Or you could define the template function with a type template parameter. But again the function parameter has a referenced type.

#include <iostream>

template <typename T>
void print( const T &a )
{
std::cout << sizeof( a ) << '\n';
}

int main()
{
int arr[10];

std::cout << sizeof( arr ) << '\n';

print( arr );

return 0;
}

The program output will be the same as shown above.

Why do we use zero length array instead of pointers?

These are various forms of the so-called "struct hack", discussed in question 2.6 of the comp.lang.c FAQ.

Defining an array of size 0 is actually illegal in C, and has been at least since the 1989 ANSI standard. Some compilers permit it as an extension, but relying on that leads to non-portable code.

A more portable way to implement this is to use an array of length 1, for example:

struct foo {
size_t len;
char str[1];
};

You could allocate more than sizeof (struct foo) bytes, using len to keep track of the allocated size, and then access str[N] to get the Nth element of the array. Since C compilers typically don't do array bounds checking, this would generally "work". But, strictly speaking, the behavior is undefined.

The 1999 ISO standard added a feature called "flexible array members", intended to replace this usage:

struct foo {
size_t len;
char str[];
};

You can deal with these in the same way as the older struct hack, but the behavior is well defined. But you have to do all the bookkeeping yourself; sizeof (struct foo) still doesn't include the size of the array, for example.

You can, of course, use a pointer instead:

struct bar {
size_t len;
char *ptr;
};

And this is a perfectly good approach, but it has different semantics. The main advantage of the "struct hack", or of flexible array members, is that the array is allocated contiguously with the rest of the structure, and you can copy the array along with the structure using memcpy (as long as the target has been properly allocated). With a pointer, the array is allocated separately -- which may or may not be exactly what you want.

Int array accept 1 more element in c than declared size

As funny as it sounds, This was caused because of the space after %d in the scanf statement. When that space was removed I was able to input and output exactly 5 elements.

[Before removing the space:]
https://i.stack.imgur.com/Gv13S.png

[After removing the space:]
https://i.stack.imgur.com/TvdvG.png



Related Topics



Leave a reply



Submit