C Expanding Integer Array - c

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

Related

Create an array based on the input size

I am pretty new to C and I am trying to read the user input (some sentence or string in general) and then I want to create an array based on the input lenght. Is there a reasonable way to do it? Thanks for answers
Just for an overview of why all the answers are suggesting pointers instead of arrays:
When I was learning C one thing that helped was to understand arrays and pointers and how similar they are.
For the most part, they can have the same syntax, you can use * syntax with either or you can use [] syntax with either.
The differences are:
1) Arrays have memory allocated for them by the system and pointers don't, you have to "set" a pointer to some memory that you have allocated.
2) I don't think arrays can change where arrays point, they always point at their pre-allocated spot.
Since arrays are pre-allocated and can't be repointed, you want a pointer. You can treat it exactly as an array (You can use [] syntax) but you have to allocate memory for it first.
So for example, if a array with and p is a pointer, a[0]=1, *a=1, p[0]=1 and *p=1 are all identical functions, and while *++p=1 is valid, I don't think *++a=1 is valid because you can't change where a points.
So the short version would be, you need a pointer, not an array, and to change how much is allocated, you allocate the new size (With malloc or something similar), copy what you want to retain over and free the old space (Or you might be able to increase the size of the first one--realloc?, not sure, my C is decades old)
malloc/free, in the case of strings a strlen will get you it's length.
You can use malloc to allocate new memory, Note that since C's memory isn't managed (contrary to Java, Python or any other high level language), you will have to free the memory once you are done using it.
int arr_size = 0;
int* arr;
printf("Please enter a size to the array:");
scanf("%d", &arr_size);
arr = malloc(arr_size * sizeof(int))
// Use array
free(arr);
void *malloc(size_t size);
The malloc() function allocates size bytes and returns a pointer to
the allocated memory. The memory is not initialized. If size is 0,
then malloc() returns either NULL, or a unique pointer value that can
later be successfully passed to free().
It depends on the standard you're compiling against and your compiler. You can only rely on variable length arrays in C99
The only way to be certain is to use malloc, though you need to ensure you free the memory afterwards:
int length;
// Do something to set the size
// Allocates a contiguous block of memory that is
// (length * size of a char primitive) in length
char *array = (char *)malloc(length * sizeof(char));
// Do whatever you need do to with the array
free(array);
In C, declaring a variable as a pointer (char *a) and as an array (char a[3]) allows you to use that variable in exactly the same way. The only difference is that with a pointer you need to allocate and free the memory yourself, while with the array that block of memory is given to you automatically and it is freed when it goes out of scope.
With the code above, you can still access each individual character via an index like so:
array[0] = 'f';
array[1] = 'o';
array[3] = 'o';

Initially mallocate 0 elements to later reallocate and measure size

I have a function that will add a new position to an array by reallocating new memory every time it is called.
The problem is that, for each call I need it to add one position to the array, starting from 1 at first call, but I understand that I have to mallocate before reallocating.
So my question is, can I initially do something like p = malloc(0) and then reallocate for example using p = (int *)realloc(p,sizeof(int)) inside my function? p is declared as int *p.
Maybe with a different syntax?
Of course I could make a condition in my function that would mallocate if memory hasn't been allocated before and reallocate if it has, but I am looking for a better way.
And the second problem I have is... Once reallocated more positions, I want to know the size of the array.
I know that if, for example, I declare an array a[10], the number of elements would be defined by sizeof(a)/sizeof(a[0]), but for some reason that doesn't work with arrays declared as pointers and then reallocated.
Any advice?
You could initialize your pointer to NULL, so that the first time you call realloc(yourPointer, yourSize), it will return the same value as malloc(yourSize).
For your second problem, you could use a struct that contains your pointer and a count member.
struct MyIntVector {
int * ptr;
size_t count;
}
Then you probably will want to define wrapper functions for malloc, realloc, and free (where you could reset ptr to NULL), that takes your struct as one of the parameters, and updates the struct as needed.
If you want to optimize this for pushing 1 element at a time, you could add a allocatedCount member, and only realloc if count == allocatedCount, with a new allocatedCount equals (for example) twice the old allocatedCount.
You should implement this in a MyIntVector_Push(MyIntVector *, int ) function.
You will then have a simplified c version of c++ std::vector<int> (but without automatic deallocation when the object goes out of scope).
As ThreeStarProgrammer57 said just use realloc.
realloc(NULL, nr_of_bytes) is equivalent to malloc(nr_of_bytes)
so
p = realloc(p, your_new_size)
will work just fine the first time if p is initialized to NULL. But be sure to pass the number of bytes you need after resizing, not the additional space that you want, as you have written your question.
As regarding the size, you have to keep track of it. That's the way C was designed.

Delete the content of a int * in 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...

Dynamic Array printing

I am trying to print a dynamic array, but I am having trouble with the bounds for the array.
For a simple example, lets say I'm trying to loop through an array of ints. How can I get the size of the array? I was trying to divide the size of the array by the size of the type like this sizeof(list)/sizeof(int) but that was not working correctly. I understand that I was trying to divide the size of the pointer by the type.
int *list
// Populate list
int i;
for(i = 0; i < ????; i++)
printf("%d", list[i]);
With dynamic arrays you need to maintain a pointer to the beginning address of the array and a value that holds the number of elements in that array. There may be other ways, but this is the easiest way I can think of.
sizeof(list) will also return 4 because the compiler is calculating the size of an integer pointer, not the size of your array, and this will always be four bytes (depending on your compiler).
YOU should know the size of the array, as you are who allocated it.
sizeof is an operator, which means it does its job at compile time. It will give you the size of an object, but not the length of an array.
So, sizeof(int*) is 32/62-bit depending on architecture.
Take a look at std::vector.
There is no standardized method to get the size of allocated memory block. You should keep size of list in unsigned listSize like this:
int *list;
unsigned listSize;
list = malloc(x * sizeof(int));
listSize = x;
If you are coding in C++, then it is better to use STL container like std::vector<>
As you wrote, you really did tried to divide the size of a pointer since list is declared as a pointer, and not an array. In those cases, you should keep the size of the list during the build of it, or finish the list with a special cell, say NULL, or anything else that will not be used in the array.
Seeing some of the inapropriate links to C++ tools for a C question, here is an answer for modern C.
Your ideas of what went wrong are quite correct, as you did it you only have a pointer, no size information about the allocation.
Modern C has variable length arrays (VLA) that you can either use directly or via malloc. Direcly:
int list[n];
and then your idea with the sizeof works out of the box, even if you changed your n in the mean time. This use is to be taken with a bit of care, since this is allocated on the stack. You shouldn't reserve too much, here. For a use with malloc:
int (list*)[n] = malloc(*list);
Then you'd have to adapt your code a bit basically putting a (*list) everywhere you had just list.
If by size you mean the number of elements then you could keep it in a counter that gets a ++ each time you push an element or if you dont mind the lost cycles you could make a function that gets a copy of the pointer to the first location, runs thru the list keeping a counter until it finds a k.next==null. or you could keep a list that as a next and a prev that way you wouldnt care if you lost the beginning.

c - dynamic memory

Hi everyone out there very first thanks to all of you for providing help.
Now i want to know about double pointer. I'm doing code like this:
int main()
{
int **a;
a = (int*)malloc(sizeof(*int)*5);
for (i=0;i<5;i++)
{
a[i] = malloc(sizeof(int)*3);
}
}
Now i dont know if I'm doing it right. How can I put values in this type of array ? Can anybody explain this concept with example ? Thanks in advance.
Well, you have allocated an array equivalent in size to:
int a[5][3];
So to enter values you just do like this:
a[0][0] = 1234;
Which would put a value into the first column of the first row and
a[4][2] = 9999;
would put another value into the last column of the last row.
Since you are using malloc, you should also loop through a[i] from i = 0 to 4, and free(a[i]); and then free(a); or your program will leak memory.
All right... what you have here, basically, is a pointer-pointer, namely, the adress of an adress. You can use this kind of variable when dealing with arrays.
The first two lines of your code are equivalent to :
int* a[5]; // Declaration of an array of 5 integer pointers (a[0] till a[4]).
A "pure" C code doesn't use variable for the size of an array, so you use the malloc when you want to edit dynamically the size of the array.
Meaning, if in your code, you are not going to change the size of your arrays, you are using a very complex way to achieve a very simple goal. You could just type :
int a[5][3];
But if you do not know the size of your array, you have to use the mallocs (and then, free). What you are doing, basically, is :
Declaring an array of array;
Allocating the memory for x number of POINTER to integer arrays;
For each of these POINTERS, allocating memory for y integers.
Now that you have done this, you can use your arrays normally. For instance :
a[1][0] = 1;
will mean : in the first array [1], the first row [0] is 1.
The only difference with a standard declaration like the one above, without the mallocs, is that since you allocated memory, you'll have to free it. Which is why you don't want to lose your variable a**. At the end of your function, the pointer-to-pointer variable will be destroyed, but not the memory you allocated.

Resources