Understanding-pointer to a structure - c

I want to understand how the pointer to the structure is passed to the function argument and implemented. How is avrg_stpc[idx_u16].sum_f32 array is working?
typedef struct
{
const float * input_f32p;
float avg_f32;
float sum_f32;
float factor_f32;
unsigned int rs_u16;
} avgminmax_avg_t;
void avgminmax_AvgCalculate_vd(
avgminmax_avg_t * const avrg_stpc,
const unsigned int numOfEntrys_u16c)
{
unsigned int idx_u16 = 0u;
do
{
avrg_stpc[idx_u16].sum_f32 += (*avrg_stpc[idx_u16].input_f32p
- avrg_stpc[idx_u16].avg_f32);
avrg_stpc[idx_u16].avg_f32 = (avrg_stpc[idx_u16].sum_f32 *
avrg_stpc[idx_u16].factor_f32);
idx_u16++;
}while(idx_u16 < numOfEntrys_u16c);
}

A few points that could help you understand arrays and pointers and their relationship:
A pointer really only points to one "object", but that object might be the first in an array.
Arrays naturally decays to pointers to their first element.
And array indexing is equivalent to pointers arithmetic (for any pointer or array a and index i, the expression a[i] is exactly equal to *(a + i)).
As for your specific example code, perhaps it would be easier if you thought of it similar to this:
avgminmax_avg_t *temp_ptr = &avrg_stpc[idx_u16];
temp_ptr->sum_f32 += ...;
temp_ptr->avg_f32 = ...;
Or perhaps like:
avgminmax_avg_t temp_object = avrg_stpc[idx_u16];
temp_object.sum_f32 += ...;
temp_object.avg_f32 = ...;
avrg_stpc[idx_u16] = temp_obj;
Both the snippets above will lead to the same result as your existing code, but requires an extra temporary variable, and in the latter snippet copying of the structure twice.

avrg_stpc is regarded as an array (possibly, allocated on heap via .*alloc); since its bounds can't be known, hence the second argument to the function. See here: https://en.cppreference.com/w/c/language/operator_member_access

Related

How to declare a jagged array in a header file?

To define a jagged array, I'm using this answer by #FaisalVasi. This works perfectly. To get the (i,j)-entry of a such defined array, type (*jagged[i])[j].
However, I like to put all my arrays in a separate file (my constant arrays), and then I have to declare them in the header file. And I don't manage to do that. I tried **jagged = unsigned[][] and *jagged = unsigned*[], and other attempts I don't remember. Anyway everything I've tried did not work. So how should I declare the jagged array in the header file?
I'm a novice in C and I hope the question is clear. Otherwise please ask me what could I clarify.
NOTE: Deviating from the requested array-of-pointers-to-rows syntax and pointing to the rows directly in the array, as proposed by #Someprogrammerdude, allows to obtain the same result, but with one less indirection and with a more clear access syntax.
direct array of rows solution
definition
unsigned jagged_row0[] = { 0, 1, 99 };
unsigned jagged_row1[] = { 1, 2, 3, 4, 5, 6, 99 };
unsigned *jagged[] = (unsigned *[]){ jagged_row0, jagged_row1 };
or in general:
type jagged_row0[] = { ... };
type jagged_row1[] = { ... };
...
type *jagged[] = (type *[]){ jagged_row0, jagged_row1, ... };
declaration
extern unsigned *jagged[];
or in general:
extern type *jagged[];
usage
unsigned v_i_j = jagged[i][j];
or in general:
type v_i_j = jagged[i][j];
original answer
The following solution addresses the definition given in the cited answer by #FaisalVasi, where the jagged array stores explicit pointers to the jagged rows.
definition (in some .c file)
unsigned jagged_row0[] = {0,1};
unsigned jagged_row1[] = {1,2,3};
unsigned (*jagged[])[] = { &jagged_row0, &jagged_row1 }; /* note the ampersand */
/* or alternatively, since compound literals are lvalues ... */
unsigned (*jagged[])[] = { &(int[]){0,1}, &(int[]){1,2,3} };
declaration
extern unsigned (*jagged[])[];
usage
unsigned *jagged_row;
...
jagged_row = *jagged[i];
unsigned v_i_j = jagged_row[j]; /* value at [i][j] */
or more compactly:
unsigned v_i_j = (*jagged[i])[j]; /* value at [i][j] */
explanation
A jagged row is an array of some basic type, in our case an array (of length determined by the static initialization) of unsigned (unsigned[]), which can be thought of, with some caveats, as a pointer to unsigned (unsigned *).
With the proposed definition, the jagged array is an array of pointers to jagged rows, which, with the same simplification, can be though of as an array of unsigned **.
When you index the first dimension, you are getting the pointer to the jagged row (an array), then you have to dereference this pointer to get to the array itself that is the jagged row, than you have to index this array to get to the final value.
A jagged array in C is usually a pointer to the first element of an array of pointers. Basically a pointer to a pointer. I.e. type **jagged.
To declare just about any variable in a header file use the extern keyword. As in
extern type **jagged;
[Replace type with the actual type]
There's two way to use it:
Full dynamic allocation
jagged = malloc(sizeof(*jagged) * M);
for (unsigned i = 0; i < M; ++i)
jagged[i] = calloc(N, sizeof(**jagged));
// Now jagged is a MxN jagged matrix where each element is zero
jagged[1][2] = 1; // Sets a single value to 1
Arrays of arrays
type jagged_row_0[] = { a, b, c };
type jagged_row_1[] = { x, y };
type **jagged = (type *[2]){ jagged_row_0, jagged_row_1 };
printf("jagged[1][0] = %d\n", jagged[1][0]);
Of course, you could make an actual array of array of pointers instead (much like the second case above):
extern type *jagged[];
...
type *jagged[] = { jagged_row_0, jagged_row_1 };
...
printf("jagged[1][0] = %d\n", jagged[1][0]);
Be very careful when having rows with different size though, so you don't go out of bounds.

Trouble working with 2d array passed by reference C

So I am working on an assignment and I am having trouble figuring out how to use this 2d array which was passed by reference.
What I am given is this
int main(){
//cap and flow initialized
maximum_flow(1000, &(cap[0][0]), &(flow[0][0]));
}
So I wanted to copy the contents of cap over to another 2d array I dynamically allocated, but after hitting an error I decided to print out the values I have in cap2 and capacity, I'm not getting back all the values that I should.
void maximum_flow(int n, int *capacity, int *flow){
int **cap2;
cap2 = (int**) malloc(sizeof(int *)*n);
for (i = 0; i < n; i++)
{
cap2[i] = (int*) malloc(sizeof(int)*n);
}
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
cap2[i][j] = (*(capacity + i*n + j));
(*(flow + i*n + j)) = 0;
}
}
}
This isn't going to be a terribly useful answer, since your code doesn't actually show the problem described; based on what's presented, I see no obvious reason why cap and cap2 shouldn't have the same contents by the end of the maximum_flow function. But I'd like to offer some background and a suggestion.
I'm going to assume cap and flow are declared as n by n arrays of int in main, where n is known at compile time.
The reason your instructor is using this interface is that passing multidimensional arrays as function arguments is problematic in C. Remember that unless it's the operand of the sizeof or unary & operators, or is a string literal being used to initialize another array in a declaraiton, an expression of type "N-element array of T" will be converted ("decay") to an expression of type "pointer to T", and the value of the expression will be the address of the first element of the array.
So, assuming a declaration like
int cap[10][10];
int flow[10][10];
the expressions cap and flow will each "decay" to type int (*)[10] (pointer to 10-element array of int). So if you wrote your function call as
maximum_flow( 1000, cap, flow );
then the function definition would have to be written as
void maximum_flow( int n, int (*cap)[10], int (*flow)[10] ) { ... }
or
void maximum_flow( int n, int cap[][10], int flow[][10] ) { ... }
In the context of a function parameter declaration, T a[][N] and T (*a)[N] mean the same thing.
The size of the outer dimension has to be specified in the array pointer declaration, and the problem is that a pointer to a 10-element array is a different, incompatible type from a pointer to an any-value-other-than-10-element array; thus, maximum_flow could only ever be used for N x 10-element arrays, limiting its usefulness. One way around this problem is to have the function receive an explicit pointer to the first element, and treat that pointer as a 1D array of size N * M.
Long story short, since you're treating your input parameters as 1D arrays, you are probably better off creating cap2 as a 1D array as well:
int *cap2 = malloc( sizeof *cap2 * n * n );
...
cap2[i * n + j] = capacity[i * n + j]; // use array subscript notation instead
flow[i * n + j] = 0; // of explicit dereferences
From the code you've posted, it's not clear what maximum_flow is supposed to do, nor why you need cap2. Note also that at some point you need to free the memory allocated to cap2, otherwise you have a memory leak.
If you're using a C99 or later compiler, you should be able to use a variable-length array instead of malloc:
int cap2[n * n]; // or int cap2[n][n], but like I said above, if you're
// treating your inputs as 1D arrays, you should also treat
// cap2 as a 1D array.
The advantage of a VLA is that you don't need to know the size at compile time, and it's treated like any other auto variable, meaning the memory for it will be released when the function exits.
The disadvantage of a VLA is that you can't use it as anything but a local variable; you can't have a VLA as a struct or union member, nor can you declare one static or at file scope. Neither can you explicitly initialize a VLA.

Understanding pointer casting on struct type in C

I'm trying to understanding the pointer casting in this case.
# https://github.com/udp/json-parser/blob/master/json.c#L408
#define json_char char
typedef struct _json_object_entry
{
json_char * name;
unsigned int name_length;
struct _json_value * value;
} json_object_entry;
typedef struct _json_value
{
struct
{
unsigned int length;
json_object_entry * values;
#if defined(__cplusplus) && __cplusplus >= 201103L
decltype(values) begin () const
{ return values;
}
decltype(values) end () const
{ return values + length;
}
#endif
} object;
}
(*(json_char **) &top->u.object.values) += string_length + 1;
Due to what I see top->u.object.values has the address of the first element of values ( type : json_object_entry ), and then we get the address of values, casting it to char, .. And from here I'm lost. I don't really understand the purpose of this.
// Notes : This is two pass parser for those who wonders what is this.
Thanks
_json_value::values is a pointer to the beginning of (or into) an array of json_object_entrys. The code adjusts its value by a few bytes, e.g in order to skip a header or such before the actual data. Because the pointer is typed one can without casting only change its value in quants of sizeof(_json_object_entry), but apparently the offset can have any value, depending on some string_length. So the address of the pointer is taken, cast to the address of a char pointer (a char pointer can be changed in 1 increments), dereferenced so the result is a pointer to char residing at the same place as the real u.object.values, and then assigned to.
One should add that such code may break at run time if the architecture demands a minimal alignment for structures (possibly depending on their first element, here a pointer) and the string length can have a value which is not a multiple of that alignment. That would make the code UB. I'm not exactly sure whether the code is nominally UB if the alignment is preserved.
Author here (guilty as charged...)
In the first pass, values hasn't yet been allocated, so the parser cheats by using the same field to store the amount of memory (length) that's going to be required when it's actually allocated in the second pass.
if (state.first_pass)
(*(json_char **) &top->u.object.values) += string_length + 1;
The cast to json_char is so that we add multiples of char to the length, rather than multiples of json_object_entry.
It is a bit (...OK, more than a bit...) of a dirty hack re-using the field like that, but it was to save adding another field to json_value or using a union (C89 unions can't be anonymous, so it would have made the structure of json_value a bit weird).
There's no UB here, because we're not actually using values as an array of structs at this point, just subverting the type system and using it as an integer.
json_object_entry * values;
...
}
(*(json_char **) &top->u.object.values) += string_length + 1;
forgetting type correctness, you can collapse the & and *:
((json_char **) top->u.object.values) += string_length + 1;
top->u.object.values is indeed the pointer to first element of values array. It is typecasted to a pointer to a pointer to json_char, and then advanced string_length + 1 characters. The net result is that top->u.object.values now points (string_length + 1) json_chars ahead of what it used to.

how can one get the size of an array via a pointer? [duplicate]

This question already has answers here:
How can I get the size of an array from a pointer in C?
(16 answers)
Closed 9 years ago.
For the following scenario, how can I get the size (3) of the array a via the pointer c? What is the pattern for solving this sort of problems?
struct struct_point {
int x;
int y;
int z;
};
typedef struct struct_point point;
int test_void_pointer () {
point a[3] = {{1, 1, 1}, {2, 2, 2}};
void * b;
point * c;
b = a;
c = b;
/* get_size_p (c) */
}
You can't. The pointer is just an address, a number, and it doesn't hold any information about the data it points to except its type.
Side note: that's why they say "arrays decay to pointers". They "decay" because inherently a pointer holds less information compared to an array.
As nims points out in the comments when passing an array to a function, it automatically decays to a pointer to the first element - and doing sizeof in the function doesn't yield the expected result. Incidentally there's also a C FAQ about this.
In C, no information about the size of the array is stored with the array. You have to know how big it is to work with it safely.
There are a few techniques for working around this. If the array is declared statically in the current scope, you can determine the size as:
size_t size = (sizeof(a) / sizeof(a[0]);
This is useful if you don't want to have to update the size every time you add an element:
struct point a[] = {{1, 1, 1}, {2, 2, 2}};
size_t size = (sizeof(a) / sizeof(a[0));
But if you have an arbitrary array, that has been passed in from somewhere else, or converted to a pointer as in your example, you'll need some way of determining its size. The usual ways to do this are to pass the size in along with the array (either as a separate parameter, or as a struct containing the array), or if the array is of a type which can contain a sentinel value (a value of the given type that is not valid), you can allocate an array one bigger than you need add a sentinel to the end of the array and use that to determine when you've reached the end.
Here's how you might pass in a length as a separate argument:
struct point myfunction(struct point array[], size_t n) {
for (size_t i = 0; i < n; ++i) {
struct point p = array[i];
// do something with p ...
}
}
Or as a structure containing the length:
struct point_array {
size_t n;
struct point elems[];
}
struct point myfunction(struct point_array a) {
for (size_t i = 0; i < a.n; ++i) {
struct point p = a.elems[i];
// do something with p ...
}
}
It would probably be hard to use sentinel values with an array of struct point directly, as there is no obvious invalid value that is still of the same type, but they are commonly used for strings (arrays of char which are terminated by a '\0' character), and arrays of pointers which are terminated by a null pointer. We can use that with struct point by storing pointers to our structures rather than storing them inline in the array:
struct point *myfunction(struct point *a[]) {
for (size_t i = 0; a[i] != NULL; ++i) {
struct point *p = a[i];
// do something with p ...
}
}
There's a way to determine the length of an array, but for that you would have to mark the end of the array with another element, such as -1. Then just loop through it and find this element. The position of this element is the length.

What is the point of pointers to arrays?

So, I was reading about pointers, and came across the concept of pointers to arrays. The thing is that a pointer to an array doesn't really seem useful at all, since instead of using a pointer to have an offset to access an array element, I could just get the element directly. However I feel as if I'm missing the reason why these can be useful.
So, in short, What is the point of pointers to arrays; How and why should they be used, and do they have any practical applications?
Edit: I meant this in the context of normal/simple arrays such as:
int array[5];
Edit: As Keith Pointed out, I'm specifically asking about pointers to arrays, for example char (*ptr)[42] which is a pointer to a 42-element array of char.
Unfortunately some answers you received show misbeliefs about pointers and arrays in C, in brief:
1) Pointer to array is not the same as pointer to first element.
2) Declaring array type is not the same as declaring pointer.
You can found full description in C faq part related to common confusion between pointers and arrays: http://c-faq.com/aryptr/index.html
Adressing your question - pointer to array is usefull to pass an entire array of compile-time known size and preserve information about its size during argument passing. It is also usefull when dealing with multi dimensional arrays when you what to operate on subarray of some array.
In most expressions, an object of type "array of T" will degrade to the address of the first array element, which will have the type "pointer to T". In this sense, a pointer type can be used to represent an array of items, and is used to do so when there is need to dynamically allocate an array.
// ptr used to dynamically allocate array [n] of T
T *ptr = malloc(n * sizeof(*ptr));
In the case of a pointer to an array, then, it can be used to represent an array of arrays, and/or dynamically allocate an array of arrays. So, a pointer to an array can be used to represent a 2-dimensional array.
// ptr used to dynamically allocate 2 dimensional array [n][10] of T
T (*ptr)[10] = malloc(n * sizeof(*ptr));
True pointers to arrays (which haven't really been addressed so far) are uncommon since arrays decay to a pointer to their first element in most contexts, and since arrays are contiguous in memory by definition that is usually all that is needed. They are also somewhat impractical compared to other pointer types since array types cannot be assigned to. They are similar to function pointers in that respect.
The biggest practical difference comes from the fact that they preserve the size of the array in situations where it would otherwise be lost to pointer decay, such as function calls and returns. Take the following code for example
void function(char (*array)[10]) {
for(size_t i = 0; i < sizeof(*a); i++);
(*a)[i] = i;
}
...
char a[10];
function(&a);
Besides allowing for this application of sizeof (which isn't terribly useful since the size is known as part of the parameter), this enforces the exact size of the passing argument as part of the type, which function(char array[10]) won't do, even with [static 10].
Returning has an unusual syntax:
char (*function(void))[10] {
static char array[10];
// do something with our static array
return &array;
}
char (*a)[10] = function();
// or even
char (*b)[sizeof(*function())] = function();
I don't think I've ever come across an application of this in the wild, but it is at least possible (and legal).
If you have an array of arrays a pointer to an array becomes useful, like in the following:
typedef float Point[3];
Point points[10];
Point *p;
for (p=points;p<points+10;++p) {
...
}
Here is real-world example of using pointers to arrays:
typedef double t_matrix33[3][3];
// Result = AB
// const double (* M1)[3], const double (* M2)[3], double (* Result)[3]
void Matrix33xMatrix33( const t_matrix33 M1, const t_matrix33 M2, t_matrix33 Result ) {
t_matrix33 copy;
const t_matrix33 * A = ( const t_matrix33 * )M1; // const double (* A)[3][3] = const double (* M1)[3]
const t_matrix33 * B = ( const t_matrix33 * )M2; // const double (* B)[3][3] = const double (* M2)[3]
int Raw;
int Col;
int i;
// !!! Make copies if Result is the same as M1 and/or M2!
//const double (* A)[3][3] == double (* Result)[3]
if( A == ( const t_matrix33 * )Result ) { // cast is must -- to get rid of gcc warnings
memcpy( copy, A, sizeof( t_matrix33 ) );
A = ( const t_matrix33 * )copy;
if( B == ( const t_matrix33 * )Result ) {
B = ( const t_matrix33 * )copy;
}
}
else if( B == ( const t_matrix33 * )Result ) {
memcpy( copy, B, sizeof( t_matrix33 ) );
B = ( const t_matrix33 * )copy;
}
for( Raw = 0; Raw < 3; ++Raw ) {
for( Col = 0; Col < 3; ++Col ) {
Result[ Raw ][ Col ] = 0;
for( i = 0; i < 3; ++i ) {
Result[ Raw ][ Col ] += (*A)[ Raw ][ i ] * (*B)[ i ][ Col ];
}
}
}
};
Thanks to A and B pointers we can avoid redundant memcopies in the case of M1 and/or M2 are not the same as Result
The one I can think of at the moment is (I am sure there are others as well), you want to make multidimensional array, however you don't have any data at the moment to save in the 2nd or 3rd dimension of the array. You don't want to waste the memory by conserving the space for 2nd and 3rd dimension of the array but you plan to allocate the memory later when you have data to store, thats when pointers to arrays come handy.
Eg.
for (int i=0; i<10; i++)
(*x)[i] = malloc(N * sizeof(*x));
// take input or put data in the array
Representation Of 2d Array In C:
This site explains it quite well. This should help you removing any confusions.

Resources