Delete the content of a int * in C - c

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...

Related

Equivalence between Subscript Notation and Pointer Dereferencing

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.

How to dynamically array of pointers specifying two dimensions at run time with a single malloc() call [duplicate]

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.

C Expanding Integer Array

I am wondering on how to create an integer array in C which you can expand it by one index every time you need to store additional values. I came across malloc and realloc and sizeof, but I really don't know how they work. Can someone here give a brief example on how to accomplish this in C.
If you want to resize your array you may do this:
int* arr = malloc(n*sizeof(int)); // n is your initial required array size
// now you need more
int* temp = realloc(arr,another_size*sizeof(int));
// check if reallocation is successful
if(temp!=NULL)
arr = temp;
Here's How malloc, realloc works:
malloc man page
realloc man page

Heap allocate a 2D array (not array of pointers)

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.

How to get the length of a dynamically created array of structs in C?

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.

Resources