I need to make a Julia type corresponding to a C struct that has a fixed size array:
struct cstruct {
...
int arr[N] //N known at compile time
...
};
I have defined Julia types corresponding to other C structs with arrays like this:
type jstruct
...
arr::Ptr{Cint}
...
end
But as I understand it, this only works when arr is a pointer, not an array of a specific size. How can I ensure that the offsets of elements coming after arr remain the same in both languages?
When you define a C struct with a fixed size array (or with the array hack), the data are stored directly inline within that struct. It's not a pointer to another region. The equivalent Julia structure is:
type JStruct{N}
arr::NTuple{N,Int}
end
That will store the integers directly inline within the struct.
Note that if you want array-type operations on this object in Julia, the StaticArrays package might be useful. It uses tuples to store the elements of arrays, while also giving them an AbstractArray interface.
Related
I am trying to initialize a struct of C array in go side.
I am new to cgo. Still trying to understand the use case.
test.h
typedef struct reply {
char *name;
reply_cb callback_fn;
} reply_t;
typedef struct common {
char *name;
int count;
reply_t reply[];
} common_t;
int
init_s (common_t *service);
test.go
name := C.CString("ABCD")
defer C.free(unsafe.Pointer(name))
num := C.int(3)
r := [3]C.reply_t{{C.CString("AB"), (C.s_cb)(unsafe.Pointer(C.g_cb))},
{C.CString("BC"), (C.s_cb)(unsafe.Pointer(C.g_cb))},
{C.CString("CD"), (C.s_cb)(unsafe.Pointer(C.g_cb))}}
g := C.common_t{
name: name,
count: num,
reply : r,
}
rc := C.init_s(&g)
I am getting error on "reply: r" unknown field 'r' in struct literal of type
Any help will be appreciated. The goal is initialize and then use it values in C init_s for processing.
You cannot use a flexible array field from Go: https://go-review.googlesource.com/c/go/+/12864/.
I think the reasonong is simple: this wart of C normally requires you to perform a trick of allocating a properly-aligned memory buffer long enough to accomodate for the sizeof(struct_type) itself at the beginning of that buffer plus sizeof(array_member[0]) * array_element_count bytes. This does not map to Go's type system because in it, structs have fixed size known at compile time. If Go would not hide reply from the definition, it would refer to a zero-length field you cannot do anything useful with anyway—see #20275.
Don't be deceived by code examples where a flexible array member field is initialized with a literal: as torek pointed out, it's a GCC extension, but what is more important, it requires work on part of the compiler—that is, it analyzes the literal, understands the context it appeared in and generates a code which allocates large enough memory block to accomodate both the struct and all the members of the flexible array.
The initialization of the array in your Go code may look superficially similar but it has an important difference: it allocates a separate array which has nothing to do with the memory block of the struct it's supposed to be "put into".
What's more Go's array are different beasts than C's: in C, arrays are pointers in disguise, in Go, arrays are first-class citizens and when you assign an array or pass it to a function call, the whole array is copied by value—as opposed to "decaying into a pointer"—in C's terms.
So even if the Go compiler would not hide the reply field, assignment to it would fail.
I think you cannot directly use values of this type from Go without additional helper code written in C. For instance, to initialize values of common_t, you would write a C helper which would first allocate a memory buffer long enough and then expose to the Go code a pair of pointers: to the beginning of the buffer (of type *C.common_t), and to the first element of the array—as *C.reply_t.
If this C code is the code you own, I'd recommend to just get rid of the flexible array and maintain a pointer to a "normal" array in the reply field.
Yes, this would mean extra pointer chasing for the CPU but it will be simpler to interoperate with Go.
What is the difference between using flexible array member (FAM) or pointer member ? In the two cases, a malloc and an affectation element by element must be done. But with FAM, a memory allocation is done for the whole structure and with ptr member, a memory allocation is done for the ptr member only (see code). What are the pros ans the cons of these two methods ?
#include <stdio.h>
#include <stdlib.h>
typedef struct farr_mb {
int lg;
int arr[];
} Farr_mb;
typedef struct ptr_mb {
int lg;
int * ptr;
} Ptr_mb;
int main() {
int lg=5;
Farr_mb *a=malloc(sizeof(Farr_mb)+lg*sizeof(int));
Ptr_mb b; b.ptr=malloc(lg*sizeof(int));
for (int i=0;i<lg;i++) (a->arr)[i]=i;
for (int i=0;i<lg;i++) (b.ptr)[i]=i;
for (int i=0;i<lg;i++) printf("%d \t",(a->arr)[i]=i);
printf("\n");
for (int i=0;i<lg;i++) printf("%d \t",(b.ptr)[i]=i);
return 0;
}
Before we get to the pros and cons, let's look at some real-world examples.
Let's say we wish to implement a hash table, where each entry is a dynamically managed array of elements:
struct hash_entry {
size_t allocated;
size_t used;
element array[];
};
struct hash_table {
size_t size;
struct hash_entry **entry;
};
#define HASH_TABLE_INITIALIZER { 0, NULL }
This in fact uses both. The hash table itself is a structure with two members. The size member indicates the size of the hash table, and the entry member is a pointer to an array of hash table entry pointers. This way, each unused entry is just a NULL pointer. When adding elements to a hash table entry, the entire struct entry can be reallocated (for sizeof (struct entry) + allocates * sizeof (element) or freed, as long as the corresponding pointer in the entry member in the struct hash_table is updated accordingly.
If we used element *array instead, we would need use struct hash_entry *entry: in the struct hash_table; or allocate the struct hash_entry separately from the array; or allocate both struct hash_entry and array in the single chunk, with the array pointer pointing just after the same struct hash_entry.
The cost of that would be two extra size_ts worth of memory used for each unused hash table slot, as well as an extra pointer dereference when accessing elements. (Or, to get the address of the array, two consecutive pointer dereferences, instead of one pointer dereference plus offset.) If this is a key structure heavily used in an implementation, that cost can be visible in profiling, and negatively affect cache performance. For random accesses, the larger the element array is, the less difference there is, however; the cost is largest when the arrays are small, and fit within the same cacheline (or a few cachelines) as the allocated and used members.
We do not usually want to make the entry member in the struct hash_table a flexible array member, because that would mean you no longer can declare a hash table statically, using struct hash_table my_table = HASH_TABLE_INITIALIZER;; you would need to use a pointer to a table, and an initializer function: struct hash_table *my_table; my_table = hash_table_init(); or similar.
I do have another example of related data structures using both pointer members and flexible array members. It allows one to use variables of type matrix to represent any 2D matrix with double entries, even when a matrix is a view to another (say, a transpose, a block, a row or column vector, or even a diagonal vector); these views are all equal (unlike in e.g. GNU Scientific Library, where matrix views are represented by a separate data type). This matrix representation approach makes writing robust numerical linear algebra code easy, and the ensuing code is much more readable than when using GSL or BLAS+LAPACK. In my opinion, that is.
So, let's look at the pros and cons, from the point of view of how to choose which approach to use. (For that reason, I will not designate any feature as "pro" or "con", as the determination depends on the context, on each particular use case.)
Structures with flexible array members cannot be initialized statically. You can only refer to them via pointers.
You can declare and initialize structures with pointer members. As shown in above example, using a preprocessor initializer macro can mean you do not need an initializer function. For example, a function accepting a struct hash_table *table parameter can always resize the array of pointers using realloc(table->entry, newsize * sizeof table->entry[0]), even when table->entry is NULL. This reduces the number of functions needed, and simplifies their implementation.
Accessing an array via a pointer member can require an extra pointer dereference.
If we compare the accesses to arrays in statically initialized structures with pointer to the array, to a structure with a flexible array member referred via a static pointer, the same number of dereferences are made.
If we have a function that gets the address of a structure as a parameter, then accessing an array element via a pointer member requires two pointer dereferences, whereas accessing a flexible array element requires only one pointer dereference and one offset. If the array elements are small enough and the array index small enough, so that the accessed array element is in the same cacheline, the flexible array member access is often significantly faster. For larger arrays, the difference in performance tends to be insignificant. This does vary between hardware architectures, however.
Reallocating an array via a pointer member hides the complexity from those using the structure as an opaque variable.
This means that if we have a function that receives a pointer to a structure as a parameter, and that structure has a pointer to a dynamically allocated array, the function can reallocate that array without the caller seeing any change in the structure address itself (only structure contents change).
However, if we have a function that receives a pointer to a structure with a flexible array member, reallocating the array means reallocating the entire structure. That potentially modifies the address of the structure. Because the pointer is passed by value, the modification is not visible to the caller. Thus, a function that may resize a flexible array member, must receive a pointer to a pointer to the structure with a flexible array member.
If the function only examines the contents of a structure with a flexible array member, say counts the number of elements that fulfill some criteria, then a pointer to the structure suffices; and both the pointer and the pointed-to data can be marked const. This might help the compiler produce better code. Furthermore, all the data accessed is linear in memory, which helps more complex processors manage caching more efficiently. (To do the same with an array having a pointer member, one would need to pass the pointer to the array, as well as the size field at least, as parameters to the counting function, instead of a pointer to the structure containing those values.)
An unused/empty structure with a flexible array member can be represented by a NULL pointer (to such structure). This can be important when you have an array of arrays.
With structures with flexible array members, the outer array is just an array of pointers. With structures with pointer members, the outer array can be either an array of structures, or an array of pointers to structures.
Both can support different types of sub-arrays, if the structures have a common type tag as the first member, and you use an union of those structures. (What 'use' means in this context, is unfortunately debatable. Some claim you need to access the array via the union, I claim the visibility of such an union is sufficient because anything else will break a huge amount of existing POSIX C code; basically all server-side C code using sockets.)
Those are the major ones I can think of right now. Both forms are ubiquitous in my own code, and I have had no issues with either. (In particular, I prefer using a structure free helper function that poisons the structure to help detect use-after-free bugs in early testing; and my programs do not often have any memory-related issues.)
I will edit the above list, if I find I've missed important facets. Therefore, if you have a suggestion or think I've overlooked something above, please let me know in a comment, so I can verify and edit as appropriate.
I am writing a code which asks for a 2D array, and in that array there are names of toys and their costs. So I was wondering if there is a way that that was possible, because I tried it and it didn't really work.
Every C array has exactly one element type, but that type can be a structure or union type, or a pointer type that points to an object of one of those kinds. For example,
union int_or_string {
int as_int;
char *as_string;
};
union int_or_string[5][5];
But I wonder whether what you really want is an one-dimensional array of structures:
struct toy {
char *name;
int cost;
};
struct toy array[42];
I am not sure if your code asks for 2d arrays. I imagine an array of structs more logical:
struct toy {
char *name;
double price;
}
struct toy toys[NUMBER];
Arrays are data structures that contains data of same object type. So the answer to your question is No.
You can rather use structures for this purpose.
struct Data{
char *str;
int n;
};
struct Data data[SIZE] // Array of struct of SIZE struct Data
Towards the solution...
Well this is why there is a thing called structure. You put the name and their price-s in a structure and then all those structure variables are put in an array. (Here a simple demonstration is made which didn't use a 2d array rather 1d array of structs is used).
Example (Illustration only)
struct toy{
char name[100];
double price;
}
struct toy toyArr[50];
And then you will do something like (to get input)
for(size_t i = 0; i < 50; i++){
if( scanf("%lf",&toyArr[i].price) != 1){
fprintf(stderr,"Error in input");
exit(1);
}
if( scanf("%99s",toyArr[i].name) != 1){
fprintf(stderr,"Error in input");
exit(1);
}
...
}
Arrays are too strict...
Also as you were having confusion about array type §6.2.5
An array type describes a contiguously allocated nonempty set of
objects with a particular member object type, called the element type.1
The element type shall be complete whenever the array type is
specified. Array types are characterized by their element type and by
the number of elements in the array. An array type is said to be
derived from its element type, and if its element type is T , the
array type is sometimes called ''array of T ''. The construction of an
array type from an element type is called ''array type derivation''.
1Emphasis mine
Way of using array (on the light of your question).
That should be a particular member object type, not a mixture of types or anything like what you were thinking.
We can get ahead of this stringent type similarity by using constructs like structure etc, which provide us with exactly what you want. Then also the array is of similar struct type but as the struct can contain different types inside of it, it provides us with what you need.
My understanding of your question (its title) is that you want an array of things which are either names or numbers
You conceptually want a sum type, also known as a tagged union. You should reason with abstract data types in mind (so document first all the operations of your ADT). SICP is a freely available book explaining that notion (but it does not use C) and is a good introduction to programming in general.
C don't have sum types natively but provide you with raw union types, which can be used to build a sum type. See this example.
Perhaps you simply want an array of things having both names and numbers.... Then:
If you just want a product type (i.e. array of things which have both a name and a cost), use a struct
But arrays in C are made of components all having the same type. They are always mono-dimensional, but you could fake 2D arrays with arrays of arrays. In particular, matrixes (of varying dimension) don't exist in C, but you can quite easily mimic them (e.g. by building your own abstract data type for them).
Pointers are also very important in C. I won't dare explaining here why. You need to read some good C programming book (explaining C dynamic heap allocation and why and when arrays decay into pointers). The notions of virtual address space and of pointer aliasing are practically important.
Perhaps you don't need a huge array of mostly empty entries. In some cases, you should consider more complex data structures. Read some Introduction to Algorithms. Maybe you need some hash table. C doesn't provide these natively, but gives you enough basic building blocks to implement them (in your library).
My feeling is that you don't really need 2D arrays, but I don't know your overall problem and I could be wrong.
Consider also studying the source code some existing free software programs (e.g. on github or elsewhere). They could inspire you (in particular since coding conventions are very important in practice).
BTW, the C11 specification is downloadable as n1570 (but it is not an introduction to C programming).
Don't forget to compile with all warnings and debug info, with GCC that is gcc -Wall -Wextra -g. Improve your code to get no warnings. Then use the debugger gdb.
before you mark this as a duplicate please notice that I'm looking for a more general solution for arrays of arbitrary dimensions. I have read many posts here or in forums about making 2D or 3D arrays of integers but these are specific solutions for specific dimensions. I want a general solution for an array of any dimension.
First I need to have a type of intlist as defined below:
typedef struct{
int l // length of the list
int * e // pointer to the first element of the array
}intlist;
this actually fills the gap in C for treating arrays just as pointers. using this type I can pass arrays to functions without worrying about loosing the size.
then in the next step I want to have a mdintlist as multidimensional dynamically allocated arrays. the type definition should be something like this:
typedef struct Mdintlist{
intlist d // dimension of the array
/* second part */
}mdintlist;
there are several options for the second part. on option is that to have a pointer towards a mdintlist of lower dimension like
struct Mdintlist * c;
the other options is to use void pointers:
void * c;
I don't know how to continue it from here.
P.S. one solution could be to allocate just one block of memory and then call the elements using a function. However I would like to call the elements in array form. something like tmpmdintlist.c[1][2][3]...
Hope I have explained clearly what I want.
P.S. This is an ancient post, but for those who may end up here some of my efforts can be seen in the Cplus repo.
You can't! you can only use the function option in c, because there is no way to alter the language semantics. In c++ however you can overload the [] operator, and even though I would never do such an ugly thing (x[1][2][3] is alread y ugly, if you continue adding "dimensions" it gets really ugly), I think it would be possible.
Well, if you separate the pointers and the array lengths, you end up with much less code.
int *one_dem_array;
size_t one_dem_count[1];
int **two_dem_array;
size_t two_dem_count[2];
int ***three_dem_array;
size_t three_dem_count[3];
This way you can still use your preferred notation.
int num_at_pos = three_dem_array[4][2][3];
I am unable to understand difference between them. When the same thing is done by three of them then when we should go for Array/Structure/Union?
In an array all the elements have the same size and type, so you can't use one for an int and the other one as a double value, and so on.
In structs, every element can have a different size or type. You can use one as an int and the others for any data type you can use for a regular variable, you can also have arrays of structures.
The unions are used to use a single variable for possibly multiple data types. In a union the size of an instance equals the size of it's largest member, unlike in structs where it equals the sum of individual member sizes.
Also, essentially the syntax is very much clearer if you use a struct even for members of the same type. For example, instead of having
float ****point3d;
You could have
struct point3d_s {
float x, float y, float z;
};
point3d_s *point3d;
will declare a pointer to a 3 dimensional point, which in turn can be used as an array too.
Well, they are three totally different objects.
Use array when you should have many (well, at least two...) elements of the very same type. Mainly, when the number of them might vary.
For example: Hold all the phone numbers of students in a class.
Use struct when you should aggregate a few variables together.
For example: Hold, per a student, their name, their phone number and their address.
Use union when you should always use only one variable type out of a few possible ones.
For example: Hold, per a student, either his phone number or their email address.
Array has no padding in between its elements as compared to structure. All elements of array and structure are considered for total size calculation, while union size is equal to its maximum sized element.
Array have all elements of same type, which is no prerequisite for structure and union.
Array uses index based access for accessing its elements, while structure and union uses .element_name for accessing its elements.