I have the array : char game[10][10][3], and I want to allocate memory for the [10][10] , how should I do it?
I thought in something like char **game[3], but when I do some malloc, it says that I need to inicialize the array.
It's pretty easy to allocate:
typedef char game_board[10][10][3];
game_board* board = malloc(sizeof(game_board));
Though honestly just using it without pointers will be a lot less messy.
Remember that char **game[3] is a pointer to a pointer to an array of size 3. Note the intermediate pointer. In the original definition it's an array of 10 array of 10 arrays of length 3. There is no pointers in this structure. While both forms can be referenced like game[x][y][z] that is only because of how C has made the syntax identical. It's not a reflection on the actual structure involved.
Related
I am writing C code and I would like to heap allocate 512*256 bytes. For my own convenience I would like to be able to access the elements with the syntax array[a][b]; no arithmetic to find the right index.
Every tutorial I see online tells me to create an array of pointers that point to arrays of the rows I want in my array. This means that each subarray needs to be malloc'd and free'd individually. I am interested in a solution that only requires one call to malloc and one call to free.(Thus all elements are contiguous) I think this is possible because I will not be constructing a jagged array.
I would appreciate if anyone could share the syntax for declaring such an array.
Well, if you want to allocate array of type, you assign it into a pointer of that type.
Since 2D arrays are arrays of arrays (in your case, an array of 512 arrays of 256 chars), you should assign it into a pointer to array of 256 chars:
char (*arr)[256]=malloc(512*256);
//Now, you can, for example:
arr[500][200]=75;
(The parentheses around *arr are to make it a pointer to array, and not an array of pointers)
If you allocate the array like this, it requires two calls to free, but it allows array[a][b] style syntax and is contiguous.
char **array = malloc(512 * sizeof(char *));
array[0] = malloc(512*256);
for (int i = 1; i < 512; i++)
array[i] = array[0] + (256 * i);
See array2 here for more information: http://c-faq.com/aryptr/dynmuldimary.html
This is easy assuming you don't need compatibility with the ancient C89 standard (among current C compilers, only MSVC and a few embedded-target compilers are that backwards). Here's how you do it:
int (*array)[cols] = malloc(rows * sizeof *array);
Then array[a][b] is valid for any a in [0,rows) and b in [0,cols).
In the language of the C standard, array has variably-modified type. If you want to pass the pointer to other functions, you'll need to repeat this type in the function argument list and make sure that at least the number of columns is passed to the function (since it's needed as part of the variably-modified type).
Edit: I missed the fact that OP only cares about a fixed size, 512x256. In that case, C89 will suffice, and all you need is:
int (*array)[256] = malloc(512 * sizeof *array);
The exact same type can be used in function argument lists if you need to pass the pointer around between functions (and also as a function return type, but for this use you might want to typedef it... :-)
Since you know the size of the array ahead of time, you could create a struct type that contains a 521x256 array, and then dynamically allocate the struct.
It is possible to dynamically allocate the same kind of multidimensional array that
static char x[512][256];
gives you, but it's a wee tricky because of type decay. I only know how to do it with a typedef:
typedef char row[512];
row *x = malloc(sizeof(row) * 256);
This only lets you determine the size of the second dimension at runtime. If both dimensions can vary at runtime, you need a dope vector.
If you know the size of the array, you can typedef it, and make a pointer to it. Here is a short snippet that demonstrates this use:
#include <stdio.h>
#include <stdlib.h>
typedef int array2d[20][20];
int main() {
int i,j;
array2d *a = malloc(sizeof(array2d));
for(i=0;i!=20;i++)
for(j=0;j!=20;j++)
(*a)[i][j] = i + j;
for(i=0;i!=20;i++)
for(j=0;j!=20;j++)
printf("%d ",(*a)[i][j]);
free(a);
return 0;
}
All great answers. I just have one thing to add for old weirdos like me who enjoy "retro" coding 16 bit with old compilers like Turbo C, on old machines. Variable length arrays are wonderful, but not needed.
char (*array)[81];
int lineCount;
/* Go get your lineCount.*/
lineCount = GetFileLines("text.fil");
array = malloc(lineCount * 81);
This is how we did "VLA" back in the olden days. It works exactly the same as
char (*array)[81] = malloc(lineCount * 81); /* error pre C99 */
without the luxury of VLA.
Just my old and tarnished 2 cents.
I have a struct in my c code of about 300Bytes (5xint + 256chars), and I wish to have a good mechanism of array for handling all my 'objects' of this struct.
I want to have a global array of pointers, so that at first all indices in the array points to NULL, but then i initialize each index when I need it (malloc) and delete it when im done with it (free).
typedef struct myfiles mf;
mf* myArr[1000];
Is that what Im looking for? Pointers mixed with arrays often confuse me.
If so, just to clerify, does
mf myArr[1000];
already allocates 1000 structs on the stack, where my first suggestion only allocates 1000pointers?
You are correct. Former allocates 1000 pointers, none of which are initialized, latter initializes 1000 objects of ~300 bytes each.
To initalize to null: foo_t* foo[1000] = {NULL};
But this is still silly. Why not just mf* myArr = NULL? Now you have one pointer to uninitialized memory instead of 1000 pointers to initialized memory and one pointer to keep track of. Would you rather do
myArraySingle = malloc(sizeof(mf)*1000); or
for(int i = 0; i < 1000; i++) {
myArray[i] = malloc(1000);
}
And access by myArraySingle[300] or *(myArray[300])`? Anyway my point is syntax aside don't create this unnecessary indirection. A single pointer can point to a contiguous chunk of memory that holds a sequence of objects, much like an array, which is why pointers support array-style syntax and why array indices start at 0.
typedef struct myfiles mf;
mf* myArr[1000];
This is what you are looking for. This will allocate array of 1000 pointers to the structure mf.
You seem to understand correctly.
More accurately, I believe mf* myArr[1000] = { 0 }; would better meet your requirements, because you want a guarantee that all of the elements will be initialised to null pointers. Without an initialisation, that guarantee doesn't exist.
There is no "global" in C. You're referring to objects with static storage duration, declared at file scope.
typedef struct myfiles mf;
mf* myArr[1000];
yes, it will initialize 1000 pointers, you have to allocate memory to each one using malloc/calloc before use.
I am writing C code and I would like to heap allocate 512*256 bytes. For my own convenience I would like to be able to access the elements with the syntax array[a][b]; no arithmetic to find the right index.
Every tutorial I see online tells me to create an array of pointers that point to arrays of the rows I want in my array. This means that each subarray needs to be malloc'd and free'd individually. I am interested in a solution that only requires one call to malloc and one call to free.(Thus all elements are contiguous) I think this is possible because I will not be constructing a jagged array.
I would appreciate if anyone could share the syntax for declaring such an array.
Well, if you want to allocate array of type, you assign it into a pointer of that type.
Since 2D arrays are arrays of arrays (in your case, an array of 512 arrays of 256 chars), you should assign it into a pointer to array of 256 chars:
char (*arr)[256]=malloc(512*256);
//Now, you can, for example:
arr[500][200]=75;
(The parentheses around *arr are to make it a pointer to array, and not an array of pointers)
If you allocate the array like this, it requires two calls to free, but it allows array[a][b] style syntax and is contiguous.
char **array = malloc(512 * sizeof(char *));
array[0] = malloc(512*256);
for (int i = 1; i < 512; i++)
array[i] = array[0] + (256 * i);
See array2 here for more information: http://c-faq.com/aryptr/dynmuldimary.html
This is easy assuming you don't need compatibility with the ancient C89 standard (among current C compilers, only MSVC and a few embedded-target compilers are that backwards). Here's how you do it:
int (*array)[cols] = malloc(rows * sizeof *array);
Then array[a][b] is valid for any a in [0,rows) and b in [0,cols).
In the language of the C standard, array has variably-modified type. If you want to pass the pointer to other functions, you'll need to repeat this type in the function argument list and make sure that at least the number of columns is passed to the function (since it's needed as part of the variably-modified type).
Edit: I missed the fact that OP only cares about a fixed size, 512x256. In that case, C89 will suffice, and all you need is:
int (*array)[256] = malloc(512 * sizeof *array);
The exact same type can be used in function argument lists if you need to pass the pointer around between functions (and also as a function return type, but for this use you might want to typedef it... :-)
Since you know the size of the array ahead of time, you could create a struct type that contains a 521x256 array, and then dynamically allocate the struct.
It is possible to dynamically allocate the same kind of multidimensional array that
static char x[512][256];
gives you, but it's a wee tricky because of type decay. I only know how to do it with a typedef:
typedef char row[512];
row *x = malloc(sizeof(row) * 256);
This only lets you determine the size of the second dimension at runtime. If both dimensions can vary at runtime, you need a dope vector.
If you know the size of the array, you can typedef it, and make a pointer to it. Here is a short snippet that demonstrates this use:
#include <stdio.h>
#include <stdlib.h>
typedef int array2d[20][20];
int main() {
int i,j;
array2d *a = malloc(sizeof(array2d));
for(i=0;i!=20;i++)
for(j=0;j!=20;j++)
(*a)[i][j] = i + j;
for(i=0;i!=20;i++)
for(j=0;j!=20;j++)
printf("%d ",(*a)[i][j]);
free(a);
return 0;
}
All great answers. I just have one thing to add for old weirdos like me who enjoy "retro" coding 16 bit with old compilers like Turbo C, on old machines. Variable length arrays are wonderful, but not needed.
char (*array)[81];
int lineCount;
/* Go get your lineCount.*/
lineCount = GetFileLines("text.fil");
array = malloc(lineCount * 81);
This is how we did "VLA" back in the olden days. It works exactly the same as
char (*array)[81] = malloc(lineCount * 81); /* error pre C99 */
without the luxury of VLA.
Just my old and tarnished 2 cents.
I am currently trying to get the length of a dynamically generated array. It is an array of structs:
typedef struct _my_data_
{
unsigned int id;
double latitude;
double longitude;
unsigned int content_len;
char* name_dyn;
char* descr_dyn;
} mydata;
I intialize my array like that:
mydata* arr = (mydata*) malloc(sizeof(mydata));
And then resized it using realloc and started to fill it with data.
I then attempted to get its size using the code described here.
sizeof(arr) / sizeof(arr[0])
This operation returns 0 even though my array contains two elements.
Could someone please tell me what I'm doing wrong?
If you need to know the size of a dynamically-allocated array, you have to keep track of it yourself.
The sizeof(arr) / sizeof(arr[0]) technique only works for arrays whose size is known at compile time, and for C99's variable-length arrays.
sizeof cannot be used to find the amount of memory that you allocated dynamically using malloc. You should store this number separately, along with the pointer to the allocated chunk of memory. Moreover, you must update this number every time you use realloc or free.
mydata* arr = (mydata*) malloc(sizeof(mydata));
is a pointer and not an array. To create an array of two items of mydata, you need to do the following
mydata arr[2];
Secondly, to allocate two elements of mydata using malloc(), you need to do the following:
mydata* arr = (mydata*) malloc(sizeof(mydata) * 2);
OTOH, length for dynamically allocated memory (using malloc()) should be maintained by the programmer (in the variables) - sizeof() won't be able to track it!
You're trying to use a pretty well known trick to find the number of elements in an array. Unfortunately arr in your example is not an array, it's a pointer. So what you're getting in your sizeof division is:
sizeof(pointer) / sizeof(structure)
Which is probably always going to be 0.
What is the benefit of declaring a C structure member as in array of size 1 instead of a pointer :
struct {
a_struct_t a_member[1];
...
}b_struct;
Thanks in advance
In a typical case, a structure with a member that's declared as an array of one item will have that member as the last item in the struct. The intent is that the struct will be allocated dynamically. When it is allocated, the code will allocate space for as many items as you really want/need in that array:
struct X {
time_t birthday;
char name[1];
};
struct X *x = malloc(sizeof(*x) + 35);
x->birthday = mktime(&t);
strcpy(x->name, "no more than 35 characters");
This works particularly well for strings -- the character you've allocated in the struct gives you space for the NUL terminator, so when you do the allocation, the number of characters you allocate is exactly the strlen() of the string you're going to put there. For most other kinds of items, you normally want to subtract one from the allocation size (or just live with the allocated space being one item larger than is strictly necessary).
You can do (sort of) the same thing with a pointer, but it results in allocating the body of the struct separately from the item you refer to via the pointer. The good point is that (unlike the method above) more than one item can be allocated dynamically, where the method above only works for the last member of the struct.
What you describe are two different things entirely. If you have a pointer as a member:
a_struct_t* a_member;
then it is simply a pointer. There is no memory allocated inside of the struct to hold an a_struct_t. If, on the other hand, you have an array of size 1:
a_struct_t a_member[1];
then your struct actually has an object of type a_struct_t inside of it. From a memory standpoint, it isn't much different from just putting an object of that type inside the struct:
a_struct_t a_member;
From a usage standpoint, an array requires indirection to access the one element (i.e., you need to use *a_member instead of a_member).
"Array of size 1 instead of a pointer"? Sorry, but I don't see how this quiestion can possibly make sense. I would understand if you asked about "array of size 1 instead of an ordinary member (non-array)". But "instead of a pointer"? What does pointer have to do with this? How is it interchangeable with an array, to justify the question?
If what you really wanted to ask is why it is declared as an array of size 1 instead of non-array as in
struct {
a_struct_t a_member;
} b_struct;
then one possible explanation is the well-known idiom called "struct hack". You might see a declaration like
struct {
...
a_struct_t a_member[1];
} b_struct;
used to implement an array of flexible size as the last member of the struct object. The actual struct object is later created within a memory block that is large enough to accomodate as many array elements as necessary. But in this case the array has to be the last member of the struct, not the first one as in your example.
P.S. From time to time you might see "struct hack" implemented through an array of size 0, which is actually a constraint violation in C (i.e. a compile error).
So I think it's been stated that the main difference between pointers and arrays is that you have to allocate memory for pointers.
The tricky part about your question is that even as you allocate space for your struct, if your struct contains a pointer you have to allocate a SECOND time for the pointer, but the pointer itself would be allocated as part of the struct's allocaiton.
If your struct contained an array of 1 you would not have to allocate any additional memory, it would be stored in the struct (which you still have to allocate).
These are different things.
Such member's name is an address of allocated memory, allocated inside the struct instance itself.