How do you allocate an array comprised of fixed size array of floats ?
I tried this:
float **sub_uvs = malloc(sizeof(float [2]) * size * size);
/* Seg. fault */
sub_uvs[0][0] = 0.3;
sub_uvs[0][1] = 0.4;
Multidimensional arrays of variable size are still tricky. Several options:
Use an array of pointers to arrays. Use one malloc for the array of pointers, then loop over malloc to make each row-array. But, this is a whole different data structure.
Find a class providing memory management and multidimensional indexing methods. Perhaps Blender has one?
Use Eigen or a similar complete math library.
You will have to perform another, separate allocation for the second array, presumably using another call to MEM_allocN. You will also have to free this memory separately, using whatever deallocation function the platform provides.
The memory representation will be completely different, so even if it is syntactically more convenient in some places, it could be difficult to make this work everywhere.
or you can use following :)
float **a;
a = (float **)malloc(sizeof(float *) * size_row);
for(int i=0;i<size_row;i++)
{
a[i] = (float *)malloc(sizeof(float) * size_col);
}
a[0][0] = 0.4;
printf("%f",a[0][0]);
Related
I am trying to create a struct containing 2 Variable Length Array (buffer_size is the variable parameter acquired at run time).
Here is my code:
struct data {
float *c; //2D array
float *mtdt; //1D array
};
struct data c_matrice;
c_matrice.c = malloc((90 * sizeof (float*) * buffer_size));
c_matrice.mtdt = malloc(90 * sizeof (float*));
The idea is to link the structure's members to arrays that are dynamically allocated.
Here is the compiler error
expected « = », « , », « ; », « asm » or « __attribute__ » before « . » token
c_matrice.c = malloc((90 * sizeof (float*) * buffer_size));
And when I try to access those members, I get
subscripted value is neither array nor pointer nor vector
I haven't been able to find a solution to my problem in the previous questions. Frankly as a beginner I don't get everything. What am I missing?
EDIT 1: Ok I got rid of the first error by moving the last two lines into my main.c rather than a .h file (This was a basic stupid mistake). Now I still face the
subscripted value is neither array nor pointer nor vector
when I try to access the struct with something like this
pmoy = pow(10,(c_matrice->c[i][curve2apply]/20))*pmax;
And by the way, the whole code is really big, and what I presented you was a small part of the actual code.
What you've done here:
c_matrice.c = malloc((90 * sizeof (float*) * buffer_size));
Is allocate one long buffer of size 90 * size of pointer-to-float * buffer_size.
You have a bunch of options in how you implement a 2D array in C.
One approach is to change what you have there to:
c_matrice.c = malloc((90 * sizeof (float) * buffer_size));
So you've allocated space for 90*buffer_size floats (rather than pointers to floats).
You then need to calculate indexes yourself:
float get_matrix_element(struct data *c_matrix, size_t row, size_t column) {
return c_matrix->c[row*buffer_size+column];
}
That's a very popular and very efficient way of storing the data because it's stored as one block of memory and you can do useful things like allocate it in a single block and iterate through it without concern for structure:
float get_matrix_sum(struct data *c_matrix) {
size_t sz=buffer_size*90;
float sum=0.0f;
for(size_t i=0;i<sz;++i){
sum+=c_matrix->c[i];
}
return sum;
}
There are other ways of doing this including:
Declare a 90 long 1D array of pointers to float and then allocate rows of floats.
The downside is 91 malloc()/free() operations instead of 1.
The upside is you could allocate a ragged array with different length rows.
Declare a static (compile time) sized array float c[90][buffer_size];
Where buffer_size is a compile time constant.
The downside is it's compile time fixed (and if large and a local variable may break the stack).
The upside is managing the internal r*90+c row calculation is taken off you.
If c is a member of the struct, then you must use c_matrice.c, not c_matrice->c. And carefully note everything people tell you about c not being a two dimensional array. To allocate these, there's a ton of question/answers on SO and you must not ask that question once again. :-)
It is more than one questions. I need to deal with an NxN matrix A of integers in C. How can I allocate the memory in the heap? Is this correct?
int **A=malloc(N*sizeof(int*));
for(int i=0;i<N;i++) *(A+i)= malloc(N*sizeof(int));
I am not absolutely sure if the second line of the above code should be there to initiate the memory.
Next, suppose I want to access the element A[i, j] where i and j are the row and column indices starting from zero. It it possible to do it via dereferencing the pointer **A somehow? For example, something like (A+ni+j)? I know I have some conceptual gap here and some help will be appreciated.
not absolutely sure if the second line of the above code should be there to initiate the memory.
It needs to be there, as it actually allocates the space for the N rows carrying the N ints each you needs.
The 1st allocation only allocates the row-indexing pointers.
to access the element A[i, j] where i and j are the row and column indices starting from zero. It it possible to do it via dereferencing the pointer **
Sure, just do
A[1][1]
to access the element the 2nd element of the 2nd row.
This is identical to
*(*(A + 1) + 1)
Unrelated to you question:
Although the code you show is correct, a more robust way to code this would be:
int ** A = malloc(N * sizeof *A);
for (size_t i = 0; i < N; i++)
{
A[i] = malloc(N * sizeof *A[i]);
}
size_t is the type of choice for indexing, as it guaranteed to be large enough to hold any index value possible for the system the code is compiled for.
Also you want to add error checking to the two calls of malloc(), as it might return NULL in case of failure to allocate the amount of memory requested.
The declaration is correct, but the matrix won't occupy continuous memory space. It is array of pointers, where each pointer can point to whatever location, that was returned by malloc. For that reason addressing like (A+ni+j) does not make sense.
Assuming that compiler has support for VLA (which became optional in C11), the idiomatic way to define continuous matrix would be:
int (*matrixA)[N] = malloc(N * sizeof *matrixA);
In general, the syntax of matrix with N rows and M columns is as follows:
int (*matrix)[M] = malloc(N * sizeof *matrixA);
Notice that both M and N does not have to be given as constant expressions (thanks to VLA pointers). That is, they can be ordinary (e.g. automatic) variables.
Then, to access elements, you can use ordinary indice syntax like:
matrixA[0][0] = 100;
Finally, to relase memory for such matrices use single free, e.g.:
free(matrixA);
free(matrix);
You need to understand that 2D and higher arrays do not work well in C 89. Beginner books usually introduce 2D arrays in a very early chapter, just after 1D arrays, which leads people to assume that the natural way to represent 2-dimensional data is via a 2D array. In fact they have many tricky characteristics and should be considered an advanced feature.
If you don't know array dimensions at compile time, or if the array is large, it's almost always easier to allocate a 1D array and access via the logic
array[y*width+x];
so in your case, just call
int *A;
A = malloc(N * N * sizeof(int))
A[3*N+2] = 123; // set element A[3][2] to 123, but you can't use this syntax
It's important to note that the suggestion to use a flat array is just a suggestion, not everyone will agree with it, and 2D array handling is better in later versions of C. However I think you'll find that this method works best.
If i have an array like this one:
int * array = ...
and if i want to delete it's content, what is the fastest and most efficient way to do this in C ?
If by "deleting the content" you mean zeroing out the array, using memset should work:
size_t element_count = ... // This defines how many elements your array has
memset(array, 0, sizeof(int) * element_count);
Note that having a pointer to your array and no additional information would be insufficient: you need to provide the number of array elements as well, because it is not possible to derive this information from the pointer itself.
If you dynamically allocate memory for an array in C with
int* array = malloc(some_size);
then you free that memory with
free(array);
Fast and efficient hasn't got much to do with that procedure - it's just how it's done - but you can pretty much count on that there's no way to do it faster...
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.
I have written a some C code running on OS X 10.6, which happens to be slow so I am using valgrind to check for memory leaks etc. One of the things I have noticed whilst doing this:
If I allocate memory to a 2D array like this:
double** matrix = NULL;
allocate2D(matrix, 2, 2);
void allocate2D(double** matrix, int nrows, int ncols) {
matrix = (double**)malloc(nrows*sizeof(double*));
int i;
for(i=0;i<nrows;i++) {
matrix[i] = (double*)malloc(ncols*sizeof(double));
}
}
Then check the memory address of matrix it is 0x0.
However if I do
double** matrix = allocate2D(2,2);
double** allocate2D(int nrows, int ncols) {
double** matrix = (double**)malloc(nrows*sizeof(double*));
int i;
for(i=0;i<nrows;i++) {
matrix[i] = (double*)malloc(ncols*sizeof(double));
}
return matrix;
}
This works fine, i.e. the pointer to the newly created memory is returned.
When I also have a free2D function to free up the memory. It doesn't seem to free properly. I.e. the pointer still point to same address as before call to free, not 0x0 (which I thought might be default).
void free2D(double** matrix, int nrows) {
int i;
for(i=0;i<nrows;i++) {
free(matrix[i]);
}
free(matrix);
}
My question is: Am I misunderstanding how malloc/free work? Otherwise can someone suggest whats going on?
Alex
When you free a pointer, the value of the pointer does not change, you will have to explicitly set it to 0 if you want it to be null.
In the first example, you've only stored the pointer returned by malloc in a local variable. It's lost when the function returns.
Usual practice in the C language is to use the function's return value to pass the pointer to an allocated object back to the caller. As Armen pointed out, you can also pass a pointer to where the function should store its output:
void Allocate2D(double*** pMatrix...)
{
*pMatrix = malloc(...)
}
but I think most people would scream as soon as they see ***.
You might also consider that arrays of pointers are not an efficient implementation of matrices. Allocating each row separately contributes to memory fragmentation, malloc overhead (because each allocation involves some bookkeeping, not to mention the extra pointers you have to store), and cache misses. And each access to an element of the matrix involves 2 pointer dereferences rather than just one, which can introduce stalls. Finally, you have a lot more work to do allocating the matrix, since you have to check for failure of each malloc and cleanup everything you've already done if any of them fail.
A better approach is to use a one-dimensional array:
double *matrix;
matrix = malloc(nrows*ncols*sizeof *matrix);
then access element (i,j) as matrix[i*ncols+j]. The potential disadvantages are the multiplication (which is slow on ancient cpus but fast on modern ones) and the syntax.
A still-better approach is not to seek excess generality. Most matrix code on SO is not for advanced numerical mathematics where arbitrary matrix sizes might be needed, but for 3d gaming where 2x2, 3x3, and 4x4 are the only matrix sizes of any practical use. If that's the case, try something like
double (*matrix)[4] = malloc(4*sizeof *matrix);
and then you can access element (i,j) as matrix[i][j] with a single dereference and an extremely fast multiply-by-constant. And if your matrix is only needed at local scope or inside a structure, just declare it as:
double matrix[4][4];
If you're not extremely adept with the C type system and the declarations above, it might be best to just wrap all your matrices in structs anyway:
struct matrix4x4 {
double x[4][4];
};
Then declarations, pointer casts, allocations, etc. become a lot more familiar. The only disadvantage is that you need to do something like matrix.x[i][j] or matrix->x[i][j] (depending on whether matrix is a struct of pointer to struct) instead of matrix[i][j].
Edit: I did think of one useful property of implementing your matrices as arrays of row pointers - it makes permutation of rows a trivial operation. If your algorithms need to perform a lot of row permutation, this may be beneficial. Note that the benefit will not be much for small matrices, though, and than column permutation cannot be optimized this way.
In C++ You should pass the pointer by reference :)
Allocate2D(double**& matrix...)
As to what's going on - well you have a pointer that is NULL, you pass the copy of that pointer to the function which allocated mamory and initializes the copy of your pointer with the address of the newly allocated memory, but your original pointer remains NULL. As for free you don't need to pass by reference since only the value of the pointer is relevant. HTH
Since there are no references in C, you can pass by pointer, that is
Allocate2D(double*** pMatrix...)
{
*pMatrix = malloc(...)
}
and later call like
Allocate2D(&matrix ...)