C Array as function parameter: Size check? [duplicate] - c

This question already has answers here:
C sizeof a passed array [duplicate]
(7 answers)
How to find the size of an array (from a pointer pointing to the first element array)?
(17 answers)
Closed 7 years ago.
I wrote the following function in C:
void dummy(int* my_array, int size)
{
//my implementation
}
Is there any way to check whether size is REALLY the size of my_array?
For example, if I call the function and use for my_array an array with 4 elements but pass 5 for size, is there any way to know that 5 is not really the size of the array?
Thank you in evidence.

You're looking at it the wrong way. An array is contiguous piece of memory. In C, you can represent this concept with a pointer to its start and its size. Since your array is represented by a <my_array, size> tuple, it doesn't make sense to talk about my_array's size, since it's only the start-pointer of the array.

unfortunately, there is no such way in C. As an array is always a pointer to an arbitrary address in memory, there is no such thing as "array bounds" that can be checked.
This is why many of the C functions have that special size parameter: because there's no other way of determining an array's size.

The size of the array is however big you made it when you declared and initialized it.
int my_array[100] = {0}; has a size of 100.
int my_other_array[50] = {0}; has a size of 50.
If you want the length of the data, then you're thinking in more abstract terms than the language can handle. The length of your data is a non-measurable parameter when the language does not support it.

If my_array is dynamically allocated (with malloc) you can get the size of memory block but it depends on specific compiler. Unfortunately in most cases there is address alignments and you will not have the exact size to 1 byte but aligned to 32 bits or other.

Related

Dynamically declaring structs not working as expected [duplicate]

This question already has answers here:
How to find the size of an array (from a pointer pointing to the first element array)?
(17 answers)
Closed 5 years ago.
I'm having issues with my program, and I'm trying to break it down and I'm seeing that I'm having issues with memory allocation at a minimum.
I have a struct:
typedef struct{
int originX;
int originY;
char ticBoard[3][3];
int result;
int turn;
} simBoard;
I would expect the size of this struct (one single instance of it) to be (4 ints * 4 bytes) + (1 bye char * 3 * 3) or 25 bytes. When I run the sizeof() function on simBoard, I get a value of 28 bytes. I'm assuming that it's the 25 + 3 extra that I don't need to worry about.
The main issue is when I try to declare an array of this struct
simBoard* boardArray = (simBoard*)malloc(sizeof(simBoard)*size));
Assume size is some constant for this scenario. To my knowledge this should create an array of the simBoard struct, of size size. I should be able to go
boardArray[3]
And get the 4th item of boardArray correct? However I'm running into an issue with the memory allocation. When I run:
printf("%zu is the size of the array\n", sizeof(boardArray));
The return value is 8. I even tried to further sort out the issue:
simBoard* boardArray = (simBoard*)malloc(224);
When I ran the printf again, I'm still getting a value of 8 bytes for boardArray. If you guys could lead me in the right direction that'd be fantastic, as I'm absolutely stumped here.
Thank you!
You can indeed index the 4th struct in the array using the notation boardArray[3].
Bear in mind though that boardArray itself is a pointer type. That explains your printf output. Arrays with dynamic storage duration and pointer types are inextricably linked in C. For the avoidance of doubt, sizeof(boardArray) is sizeof(simBoard*).
C doesn't provide functionality to obtain the length of an dynamic array. You need to remember the length yourself.
Don't forget to call free(boardArray) when your done. The C runtime library will take appropriate measures to ensure that all the struct elements are freed.

Do flat and 2D arrays use the same amount of memory? [duplicate]

This question already has answers here:
How are 3D arrays stored in C?
(8 answers)
Closed 6 years ago.
While writing C-code for an answer to a question about a limited-memory situation, I wondered whether any memory space can be saved by using a flat array instead of a (rectangular) two-dimensional array (of which the size is known at compile-time).
So, does e.g. char a[200][100] use more memory space than char a[20000]?
(I know it does in some languages, but this is specifically about C)
So, does e.g. char a[200][100] use more memory space than char a[20000]?
No, char a[200][100] uses the same amount of memory as char a[20000].
Both need contiguous memory that can hold 20000 chars.
There is no difference between a[200][100] and a[20000]. For the a[200][100] C uses the number of columns to compute the offset as a is just a pointer to memory of type char. So if you wanted a[20][5] then C would compute a[20][5] = *(a + 20 * 100 + 5); I should mention that C is row major (or uses row first in computations).
So if you know the dimensions of your array, you could do the same computation with a[20000].
From a software communications standpoint, if it was static, I would use the char a[200][100] as it communications your structure is 200 rows by 100 columns. This lets the compiler do the computations for you.

Size of a dynamically allocated integer array [duplicate]

This question already has answers here:
Why isn't the size of an array parameter the same as within main?
(13 answers)
C sizeof a passed array [duplicate]
(7 answers)
size of array in c
(6 answers)
Closed 9 years ago.
I am handling a function of type:
int xyz(int input[])
I do not have access to the main function and therefore have no idea about the size of the array.
How can i find the size of the input array?
Is there any way to know where the array ends?
sizeof(input)/sizeof(int*) is giving 1 as input is basically a pointer.
If the caller doesn't provide the size information about the array then there's no way to get the size in function xyz().
You can pass the size information in another variable (or as an elemnt of the array).
int xyx(int abc[], size_t len)
{
}
No... there's no (portable) way from within the called function, so it's normal in this situation (i.e. when no number-of-elements parameter is passed) for callers to adopt some convention such as providing a sentinel value in the last used element or guarantee a set number of elements. If a sentinel is used, you might be able to prove to yourself that this was being done by checking the calling code in a debugger.
If you pass an array to a function and don't provide the length, you can't find it, because the array decays to as pointer whose size is always 32 (64) bit.

Having trouble finding the length of an array in C? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
c dynamic memory allocation and sizeof()
I am trying to find the cache block by keeping a huge block of 16 MiB and by trying to access different elements each time to find the time. I just can't write the length of the array.
How can I write a for loop to iterate over the array. I need the length of the array; how can I find that? I have tried sizeof(a)/sizeof(a[0]) but this doesn't work or I am doing something wrong because my assignment sheet tells me it can hold 4 million int's..
register *a;
a = malloc(16777216);
int i;
for (i = 0; i < sizeof(a)/sizeof(a[0]); i = i + 1) {
printf("\ni = %d", i);
}
This only prints i = 0 i = 1.
The code sizeof(a) simply returns the size of the pointer register *a, and is completely unrelated to the size of the array that a points to.
C arrays do not track how many items they contain. You can use this syntax only if the size of the array is known at compile time. But you can't do it with an array allocated this way.
For this task, you'll need to track this information yourself. You can store that value in a variable, or you could append an array element with a special value that indicates it's the end of the array (much like we do with C strings).
a is a register pointer an not an array. so sizeof(a) will not return 16MB as you are expecting. please use 16777216 directly instead of sizeof()

Flexible Array Member (Zero Length Array) [duplicate]

This question already has answers here:
Array of zero length
(5 answers)
Closed 8 years ago.
In reference to GCC's Zero Length Array explanation:
This is particularly useful in the case when a struct is a header for a variable-length object. This is exactly my case. Furthermore, I am concerned with the alignment of my structs in the heap.
In this case, I still really do not understand what's useful about zero length arrays. How are they related to this particular situation?
EDIT:
Is it that I can put as much "data" as I want in there?
Basically it allows you to have a structure with a variable length array at the end:
struct X {
int first;
int rest[0];
};
An array size of 0 is not actually valid (although it is allowed as a gcc extension). Having an unspecified size is the correct way.
Since C doesn't really care that you are accessing elements beyond the end of the array, you just start with an undefined array size, and then allocate enough memory to handle however many elements you actually want:
struct X *xp = (struct X *)malloc(sizeof(struct X)+10*sizeof(int));
xp->rest[9] = 0;
The memory returned from malloc() that you will assign to a pointer to the struct with the zero-length array member will be aligned memory ... that's required by the C99 specification. So there is no issue overlaying a struct with a zero-length array over memory allocated from the heap via malloc().
Where you would run into trouble would be attempting to overlay your struct over some raw buffer in memory that came from a packed or non-traditionally aligned data-source, such as a file-header, memory-mapped hardware interface, etc. In those cases, using a zero-length array to handle the variable-length data can be a bad idea since the data may not be aligned according to the default alignment parameters of the platform, and thus offsetting into the array will not yield the correct results.

Resources