See this example:
int *array = malloc (10 * sizeof(int))
Is there a way to free only the first 3 blocks?
Or to have an array with negative indexes, or indexes that don't begin with 0?
You can't directly free the first 3 blocks. You can do something similar by reallocating the array smaller:
/* Shift array entries to the left 3 spaces. Note the use of memmove
* and not memcpy since the areas overlap.
*/
memmove(array, array + 3, 7);
/* Reallocate memory. realloc will "probably" just shrink the previously
* allocated memory block, but it's allowed to allocate a new block of
* memory and free the old one if it so desires.
*/
int *new_array = realloc(array, 7 * sizeof(int));
if (new_array == NULL) {
perror("realloc");
exit(1);
}
/* Now array has only 7 items. */
array = new_array;
As to the second part of your question, you can increment array so it points into the middle of your memory block. You could then use negative indices:
array += 3;
int first_int = array[-3];
/* When finished remember to decrement and free. */
free(array - 3);
The same idea works in the opposite direction as well. You can subtract from array to make the starting index greater than 0. But be careful: as #David Thornley points out, this is technically invalid according to the ISO C standard and may not work on all platforms.
You can't free part of an array - you can only free() a pointer that you got from malloc() and when you do that, you'll free all of the allocation you asked for.
As far as negative or non-zero-based indices, you can do whatever you want with the pointer when you get it back from malloc(). For example:
int *array = malloc(10 * sizeof(int));
array -= 2;
Makes an array that has valid indices 2-11. For negative indices:
int *array = malloc(10 * sizeof(int));
array += 10;
Now you can access this array like array[-1], array[-4], etc.
Be sure not to access memory outside your array. This sort of funny business is usually frowned upon in C programs and by C programmers.
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
While allocating static memory in c, it can be done quite simply. But while dealing with dynamic memory why do i have to deal with pointer. one explanation is that malloc allocates the memory and returns pointer so that it can be accessed but then why same does not happen in case of static memory?
Shouldn't it be simply accessed by its name?
for eg
int *arr = (int*)malloc(sizeof(int));
First, when a program executes malloc(n), there is no name. It is not possible to refer to the object by name because there is no name that refers to the space that malloc allocated.
Consider int *p = malloc(n);. This assigns the pointer that malloc returns to p. Note that p is the name of the pointer. It is not the name of the space. *p refers to the space.
We could add a feature to C that lets us bind names to allocated space, so that int &x = *p; caused x to refer to the space. But that is not often what we want to use allocated space for. Sometimes we want to allocate many things and organize them into a linked list or a tree or other structures where one element of a structure points to other structures. We would not want to have an individual name for every structure in the program—we want to work with them dynamically, using computed pointers. For example, consider how we might add up all numbers in an array:
int sum = 0;
for (int i = 0; i < N; ++i)
sum += array[i];
We would not want to write this loop as sum = array[0] + array[1] + array[2] + …;. Aside from being tedious, we do not know how many terms to write at compile time. We want this loop to be dynamic, for the elements to be computed while the program is running. Similarly, with a linked list, we want to write:
int sum = 0;
for (int *p = Head; p; p = p->next)
sum += p->value;
So we do not want a bunch of named variables for the allocated objects. We want to be able to manipulate them with pointers.
The way you propose to handle pointers would prevent half of the use cases of pointers.
They not only allow to access the content of the memory referenced by the pointer,
they also allow to change the memory addressed by the pointer, i.e. which part of memory it refers to.
Accessing the content of the referenced memory is done like
int* arr= malloc(sizeof(int)); /* Do not cast malloc. */
*arr = 1;
Changing the memory which is referenced is done by
free(arr); /* assuming it was initialised as above */
arr= malloc(sizeof(int)*2); /* different now */
(Strictly this does not guarantee the pointer to get a different value at the second malloc, but I did not want to make an example which leaks the first allocation by not freeing beforehand.)
And also changing the accessed memory without changing the pointer:
*arr=1; /* first */
*(arr+1) =2; /* second */
The way to understand "why does malloc returns a pointer?" is by understanding arrays in C. Array in c are sequential collection of elements. For statically allocating array we define as:-
int toys[20];
toys is an array of 20 elements of type integer. Here "toys" can be considered pointer and can be accessed like it.
*(toys) = 1; // setting first element i.e toys[0] = 1;
*(toys + 1) = 25; // setting second element i.e toys[1] = 25;
*(toys + 4) = 60; //setting 5th element i.e toys[4] = 60;
Now, looking into manual of malloc.
void * malloc(size_t size);
The malloc() function allocates size bytes of memory and returns a
pointer to the allocated memory.
Malloc always allocates memory in chunk (i.e, collection or array). so
p = malloc (8 )
allocates 8 bytes and return void type pointer of the 8 bytes, i.e. equivalent to static code below.
void test[8];
To get the pointer of desired type, the returned pointer is type casted as below:-
int * myToys = (int *) malloc ( sizeof(int) * 20 ); // same as, int mytoys[20];
PS:- Pointers and arrays are correlated. Malloc always returns array of bytes, so it returns pointer.
I have an 2d array . The 1st dimension has fixed size and i dynamicly create the 2nd dimension. e.g
int **arr;
*arr=( int * ) malloc ( X * sizeof ( int )) // X is input from user
What i want to do is create 2nd dimension and write value at the end of it.
For example i create 2nd dimension for arr[0] using
arr[0]=( int * ) malloc ( 2 * sizeof ( int ))
and then i want to write value in this 2nd dimension but without knowing the index. A lot of programming languages has method array.push which push item at the end of the array without knowing index or length of the array. How can i achieve such result in C? Is it possible?
Short answer: NO. You need to know the last index of the memory allocated via a pointer. There is no way of knowing the memory allocated for a pointer, so you need to know the last index for each column. Applying sizeof on a pointer gives you the memory occupied by a pointer (most often 4 or 8 bytes), and not the memory allocated by the pointer. This is a fundamental difference between pointers and arrays. They are not the same, although arrays decay to pointers when passed as arguments to functions.
Assuming your 2D array has NROWS and NCOLS, what you need is:
arr = malloc(NROWS * sizeof(int*)); // allocate memory for first dim, i.e. for rows
then allocate memory for each row, e.g. for the 5-th row:
arr[5] = malloc(NCOLS * sizeof(int)); // allocate NCOLS for the 5-th row
In general you allocate memory for the second dimension in a loop:
for(size_t i = 0 ; i < NCOLS; ++i)
free(arr[i]);
Then don't forget to release the memory at the end, in reverse order:
for(size_t i = 0; i < NCOLS; ++i)
free(arr[i]); // release memory for cols
free(arr); // release memory for rows
However, I recommend you use a 1D array instead (in case the dimension is the same for each column), and map from 1D to 2D and viceversa. It's better this way since the data is stored contiguously (better data locality) and there are no cache misses.
If you switch to C++, then you can use the standard container std::vector, which "knows" its indexes, and you can add at the end via std::vector::push_back or std::vector::emplace_back member functions.
I want to create 5*5 2D Matrix. I usually use the following way of memory allocation:
int **M = malloc(5 * sizeof(int *));
for (i = 0; i < 5; i++)
{
M[i] = malloc(5 * sizeof(int));
}
While I was reading a blog, I found also another way to do that:
int **M = malloc(5 * sizeof(int*));
M[0] = malloc((5*5) * sizeof(int));
My question is: What is the difference between both methods? Which one in more efficient?
For the second code, note that you need to initialize the other array members for it to work correctly:
for (int i = 1; i < 5; i++) {
M[i] = M[0] + i * 5;
}
So in the second code the arrays members (through all arrays) are contiguous. It does not make any difference to access them (e.g., you an still access them using M[i][j] syntax). It has the advantage over the first code to require only two malloc calls and as mentioned in the comments to favor caching which can greatly improve the access performances.
But if you plan to dynamically allocate large arrays, it is better to use the first method because of memory fragmentation (large contiguous memory allocation can be not available or can exacerbate memory fragmentation).
A similar example of this kind of dynamic allocation of arrays of arrays can be found in the c-faq: http://c-faq.com/aryptr/dynmuldimary.html
After seeing ouah's answer and seeing the example in the C FAQ, I now understand where the second technique comes from, although I personally wouldn't use it where I could help it.
The main problem with the first approach you show is that the rows in the array are not guaranteed to be adjacent in memory; IOW, the object immediately following M[0][4] is not necessarily M[1][0]. If two rows are allocated from different pages, that could degrade runtime performance.
The second approach guarantees that all the rows will be allocated contiguously, but you have to manually assign M[1] through M[4] to get the normal M[i][j] subscripting to work, as in
for ( size_t i = 0; i < 5; i++ )
M[i] = M[i-1] + 5;
IMO it's a clumsy approach compared to the following:
int (*M)[5] = malloc( sizeof *M * 5 );
This also guarantees that the memory is allocated contiguously, and the M[i][j] subscripting works without any further effort.
However, there is a drawback; on compilers that don't support variable-length arrays, the array size must be known at compile time. Unless your compiler supports VLAs, you can't do something like
size_t cols;
...
int (*M)[cols] = malloc( sizeof *M * rows );
In that case, the M[0] = malloc( rows * cols * sizeof *M[0]) followed by manually assigning M[1] through M[rows - 1] would be a reasonable substitute.
I hope I'm not missing something here but here's my attempt to answer the question "What is the difference...". If I am completely off base, forgive me and I will correct my answer but here goes:
I tried drawing out what is happening in your two mallocs so what I have to say is tied to the picture included which I drew by hand (hand crafted answers?)
First option:
For the first option, you allocate a memory block the size of 5 int*s. M, which is an int** points to the start of that memory block.
Then, you go over each of the memory blocks (the size of int*) and in each block you put in the address of a memory block the size of 5 ints. Note that these are located in some random portion of your memory (the heap) that has enough space to take the size of 5 ints.
This is the key - it's a noncontiguous block of memory. So if you think about memory as an array, you are pointing at different start locations in the array.
Second Option
Your second does the allocation of int** exactly the same. But instead, it allocates the size of 25 ints and returns places the address of that array in the memory block M[0]. Note: you've never placed any address in the memory locations M[1] - M[4].
So, what happens? You have a contiguous block of 25 ints with an address that can be found in M[0]. What happens when you try getting M[1]? You guessed it - it's empty or contains junk values. Even more, it's a value that does not point to an allocated memory space so you Segfault.
If you want to allocate a 5x5 array in contiguous memory, the correct approach would be
int rows = 5;
int cols = 5;
int (*M)[cols] = malloc(rows * sizeof(*M));
You can then access the array with normal array indexing, e.g.
M[3][2] = 6;
int **M = malloc(5 * sizeof(int *)); refers to allocating memory for a pointer M[i] = malloc(5 * sizeof(int)); refers to allocating memory for a variable of int.
Maybe this will help you understand what is going on:
int **M = malloc(5 * sizeof(void *));
/* size of 'void *' and size of 'int *' are the same */
for (i = 0; i < 5; i++)
{
M[i] = malloc(5 * sizeof(int));
}
Another little difference when using malloc((5*5) * sizeof(int));. Certainly a side issue to what OP is looking for, but still a concern.
Both of the below are the same as the order of the 2 operands still result in using size_t math for the product.
#define N 5
malloc(N * sizeof(int));
malloc(sizeof(int) * N);
Consider:
#define N some_large_value
malloc((N*N) * sizeof(int));
The type of the result of sizeof() is type size_t, an unsigned integer type, that is certainly has SIZE_MAX >= INT_MAX, possible far larger. so to avoid int overflow that does not overflow size_t math use
malloc(sizeof(int) * N * N);
I want to allot memory dynamically for a 2D array.
Is there any difference between these two ?
1)
array = (int**)malloc(size * sizeof(int*));
for (i = 0; i < size; i++) {
array[i] = (int *) malloc(size * sizeof(int));
}
2)
array = (int**)malloc(size *size* sizeof(int));
If yes, what is better to use and why ?
In the first case
array = (int**)malloc(size * sizeof(int*));
for (i = 0; i < size; i++) {
array[i] = (int *) malloc(size * sizeof(int));
}
you are allocating size extents of the size equal to size * sizeof( int ) That is you are allocating size one-dimensional arrays. Accordingly you are allocating size pointers that point to first elements of these one-dimensional arrays.
In the second case expression
(int**)malloc(size *size* sizeof(int))
means allocation of an extent of size * size of objects of type int and the returned pointer is interpretated as int **. So this expression has no sense independing on what is placed in the left side of the assignment. take into account that the size of pointer can be greater than the size of int.
You could write instead
int ( *array )[size] = ( int (*)[size] )malloc(size *size* sizeof(int));
In this case you are indeed allocating a two dimensional array provided that size is a constant expression.
Those two solutions are very different. The first will give you a vector of pointers to vectors. The second will give you a vector of the requested size. It all depends on your use case. Which do you want?
When it comes to releasing the memory, the first can only be freed by calling free for each pointer in the vector and then a final free on the vector itself. The second can be freed with a single call. Don't have that be your deciding reason to use one or the other. It all depends on your use case.
What is the type of the object you want to allocate? Is it an int **, an int *[] or an int[][]?
I want to allot memory dynamically for a 2 dimensional array.
Then just do
int (*arr)[size] = malloc(size * sizeof *arr);
Is there any difference between these two ?
Yes, they are wrong because of different errors. The first attempt does not allocate a 2D array, it allocates an array of pointers and then a bunch of arrays of ints. Hence the result will not necessarily be contiguous in memory (and anyway, a pointer-to-pointer is not the same thing as a two-dimensional array.)
The second piece of code does allocate a contiguous block of memory, but then you are treating it as if it was a pointer-to-pointer, which is still not the same thing.
Oh, and actually, both snippets have a common error: the act of casting the return value of malloc().
I have dynamically allocated 2D array.
Here is the code
int **arrofptr ;
arrofptr = (int **)malloc(sizeof(int *) * 2);
arrofptr[0] = (int *)malloc(sizeof(int)*6144);
arrofptr[1] = (int *)malloc(sizeof(int)*4800);
Now i have to know that how many bytes are allocated in arrofptr,arrofptr[0],arrofptr[1]?
is there any way to know the size?
if we will print
sizeof(arrofptr);
sizeof(arrofptr[0]);
sizeof(arrofptr[1]);
then it will print 4.
You can't find size of arrofptr, because it is only a pointer to pointer. You are defining an array of arrays using that. There's no way to tell the size information with only a pointer, you need to maintain the size information yourself.
The only return value you get from malloc() is a pointer to the first byte of the allocated region (or NULL on failure). There is no portable, standard, way of getting the associated allocation size from such a pointer, so in general the answer is no.
The C way is to represent arrays and buffers in general with a pair of values: a base address and a size. The latter is typically of the type size_t, the same as the argument to malloc(), by the way.
if you want to keep track of the size of an allocated block of code you would need to store that information in the memory block that you allocate e.g.
// allocate 1000 ints plus one int to store size
int* p = malloc(1000*sizeof(int) + sizeof(int));
*p = (int)(1000*sizeof(int));
p += sizeof(int);
...
void foo(int *p)
{
if (p)
{
--p;
printf( "p size is %d bytes", *p );
}
}
alt. put in a struct
struct
{
int size;
int *array;
} s;
You can't get the length of dynamically allocated arrays in C (2D or otherwise). If you need that information save it to a variable (or at least a way to calculate it) when the memory is initially allocated and pass the pointer to the memory and the size of the memory around together.
In your test case above sizeof is returning the size of the pointer, and thus your calculation the size of the pointers is usually 4, this is why you got 4 and is likely to have the trivial result of 4, always.