Dynamic allocation of memory for an array in C - c

I just wanted to ask that is there any way to dynamically allocate memory to an existing array of elements at runtime in C? For example.. if i declared int arr[25]; then I would be able to take maximum of 25 integers in my array.. But what if the user wants to enter some more integers.. but we dont know in advance how many? Also I dont want to waste the memory by assigning something like int arr[500]; just to be sure that the user doesnt exceed the upper bound of my array :( I'm really confused and sad as I'm unable to find a solution for this.. Does C even support such kind of thing? If not then in which programming language would it be easier to tackle a problem like this? P.S-> I'm new to programming so I'm sorry if this is a noob question. :/

you need to do dynamic memory allocation using malloc()/realloc() and release it using free() once you are done.
int* a = malloc(25*sizeof(int));
//use a like array...a[0]...to a[24]
// realloacte if you need to grow it
a = realloc(a,50);
free(a);
The above logic should be used in C. If you are writing into C++, you should use STL std::vector<T>

if it is an array you might actually want to check out the calloc() function:
void* calloc (size_t num, size_t size);
It can be used like so:
/* calloc example */
#include <stdio.h> /* printf, scanf, NULL */
#include <stdlib.h> /* calloc, exit, free */
int main ()
{
int i,n;
int * pData;
printf ("Amount of numbers to be entered: ");
scanf ("%d",&i);
pData = (int*) calloc (i,sizeof(int));
if (pData==NULL) exit (1);
for (n=0;n<i;n++)
{
printf ("Enter number #%d: ",n+1);
scanf ("%d",&pData[n]);
}
printf ("You have entered: ");
for (n=0;n<i;n++) printf ("%d ",pData[n]);
free (pData);
return 0;
}
If you need to resize the array later look at the realloc function. (and yes it does keep the original data if succesfull)

There is a class in c++ that you may find useful, which is called a vector. You can add to the front of a vector: myVector.push_front(myElement) and to the end of a vector: myVector.push_back(myElement). If this type of functionality is very important to you, I would recommend using a c++ vector.
Alternately, you can use the malloc() function in c to request a specific amount of memory at runtime: char *five_chars = malloc(sizeof(char) * 5). Just be sure to call free(five_chars) when you're done with the memory.

Related

Is this the right way to free a dynamic string I'm using in multiple functions in C?

I made a simple base converter and the very first thing it does is it gets a string from the user. I wanted the string to be dynamic, so I did this:
char *getStr() {
char *str = NULL;
/*LOOP THAT USES getc() TO SAVE CHARS INTO THE STRING AND GROWS IT USING realloc() IF NEEDED*/
return str;
}
int main() {
char *str;
str = getStr();
//SOME STUFF HAPPENS HERE WITH THE str. IT REMAINS THE SAME LENGTH.
free(str) //IS THIS THE RIGHT PLACE TO FREE IT?
}
So, is free() in the right place here? I understand that since both str pointers point to the same address it should work, right? Also, by the way, how does free() know where to stop deallocating, when it only has the first address?
This may be pretty obvious, but I wanna make sure.
In your example, this is the right place for it.
The simplest free are called when you are just no need for the data anymore.
The tricky part in my experience is when things don't go as planned, or when your program can exit with multiple ways.
Take a look at this dummy program that has absolutely no real purpose.
A program that takes an integer, if this integer has a value superior to 10, the program will add 1 to it. If not, it will exit the whole program with exit (1)
static void add_one_to_num(int *num)
{
if (*num < 10)
{
free(num);
exit(1);
}
*num = *num + 1;
}
int main()
{
int *num;
num = malloc(sizeof(int));
printf("Enter a number higher than 10: ");
scanf("%d", num);
add_one_to_num(num);
printf("num: %d\n", *num);
free(num);
return (0);
}
In this program, we might exit at the function add_one_to_num so you need to free that pointer in that place.
By writing more and more programs you will get the hang of it, because it's actually very logical and not at all chaotic (It could be a pain in the neck for large programs to track down all allocated memories throughout all the functions the pointers are passed to ).
just make sure to free when you longer need the data, or when something changes the natural flow of your program.

Appending element into an array of strings in C

I have an array of strings with a given size, without using any memory allocation, how do I append something into it?
Say I run the code, its waiting for something you want to enter, you enter "bond", how do I append this into an array ? A[10] ?
If the array declared like
char A[10];
then you can assign string "bond" to it the following way
#include <string.h>
//...
strcpy( A, "bond" );
If you want to append the array with some other string then you can write
#include <string.h>
//...
strcpy( A, "bond" );
strcat( A, " john" );
You can't append to an array. When you define the array variable, C asks the is for enough contiguous memory. That's all the memory you ever get. You can modify the elements of the array (A[10]=5) but not the size.
However, you CAN create data structures that allow appending. The two most common are linked lists and dynamic arrays. Note, these are no built into the language. You have to implement them yourself or use a library. The lists and arrays of Python, Ruby and JavaScript are implemented as dynamic arrays.
LearnCThHardWay has a pretty good tutorial on linked lists, though the one on dynamic arrays is a little rough.
Hi,
It really depends on what you mean by append.
...
int tab[5]; // Your tab, with given size
// Fill the tab, however suits you.
// You then realize at some point you needed more room in the array
tab[6] = 5; // You CAN'T do that, obviously. Memory is not allocated.
The problem here can be two things :
Did you misjudge the size you need ? In that case, just make sure this given size you mentioned is correctly 'given', however that might be.
Or don't you know how much room you want at the beginning ? In that case, you''ll have to allocate the memory yourself ! There is no other way you can resize a memory chunk on the fly, if I might say.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define STR_MAX_SIZE 255 // Maximum size for a string. Completely arbitray.
char *new_string(char *str)
{
char *ret; // The future new string;
ret = (char *) malloc(sizeof(char) * 255); // Allocate the string
strcpy(ret, str); // Function from the C string.h standard library
return (ret);
}
int main()
{
char *strings[STR_MAX_SIZE]; // Your array
char in[255]; // The current buffer
int i = 0, j = 0; // iterators
while (in[0] != 'q')
{
printf("Hi ! Enter smth :\n");
scanf("%s", in);
strings[i] = new_string(in); // Creation of the new string, with call to malloc
i++;
}
for ( ; j < i ; j++)
{
printf("Tab[ %d ] :\t%s\n", j, strings[j]); // Display
free(strings[j]); // Memory released. Important, your program
// should free every bit it malloc's before exiting
}
return (0);
}
This is the easiest solution I could think of. It's probably not the best, but I just wanted to show you the whole process. I could have used the C standard library strdup(char *str) function to create a new string, and could have implemented my own quick list or array.
The size of an array variable cannot change. The only way to append to an array is to use memory allocation. You are looking for the realloc() function.
If you want to append a character or string to it;
strcpy(a, "james")
strcpy(a, "bond")

Why will this not print?

Before you feel the need to mark this as a duplicate post, please don't. I have read all the threads on pointers, arrays, and functions I could find but almost all of them are far too advanced to be of any help to me.
I'm not getting an error, however my code will not print my array. It seems the issue here is using scanf. I don't think the values entered are actually being put into the array in main(). I've tried using pointers, but then I get the error "Thread 1: EXC_BAD_ACCESS (code=1, address=0x0)" whenever I try to use scanf to collect user inputted values to put into the array.
What I am working on is limited to declaring my array in the main() function, but all the operations are to be performed in promptData() function. Any help would be great, I'm at my wits end trying to figure this out on my own.
#import <stdio.h>
void promptData(double data[], int numElem);
int main(int argc, const char * argv[])
{
int size, i;
double array[size];
promptData(array, size);
for (i = 0; i < size; i++)
printf("%.2lf\n", array[i]);
return 0;
}
void promptData(double data[], int numElem)
{
int i;
printf("Enter integer values for size of array.\n");
scanf("%i", &numElem);
for (i = 0; i < numElem; i++)
{
printf("Enter array values.\n");
scanf("%lf", &data[i]);
}
}
Your program has undefined behaviour because variable size was not initialized and has indeterminate value.
You should at first in main ask the user to enter the size of the array then define the array itself and only after that fill it with values.
For example
int main(int argc, const char * argv[])
{
int size = 0;
printf( "Enter a positive integer value for the size of the array: ");
scanf( "%i", &size);
if ( size == 0 ) exit( 1 );
double array[size];
promptData(array, size);
//...
Also in C there is no such a directive as
#import <stdio.h>
Use instead
#include <stdio.h>
At least in ANSI C 89 and C 90, you can't give a variable as the size of an array. The size of array should be known at compile time. You should be doing something like double array[size];.
Even in C99, where you can have variable sized arrays; the variables should contain proper index values at the time you declare the array. In that case, you should read the number from stdin and then declare the array.
Also in C, all parameters are passed by value. This means every function takes a copy of the parameters in the function. If you want to modify a variable's value, you should pass a pointer to it, and then modify the pointer's dereferenced value, something like:
void change(int *x)
{
*x = 7;
}
void first(void)
{
int x = 5;
change(&x);
printf("%d\n", x);
}
Adding on to the other, correct, answer by Zenith, if you want a dynamically allocated array (like you want to be able to change its size based on user input), then your only option is to use one of the memory allocation functions like malloc().
Once you actually have the size in your main function, declare your array like this:
int *myArray = malloc(sizeof(int) * size));//note that malloc will return a NULL if it fails
//you should always check
if(myArray != null) {
//do stuff with myArray like you were. You can just use myArray[] as long as you
//make SURE that you don't go beyond 'size'
}
free(myArray);
//VERY important that every malloc() has a free() with it
Note: untested, but the idea is there.
Further, to answer your other question.
If you find yourself in a situation where you need to call a function and use things INSIDE that function to change stuff where you called it, you have only two choices in C.
You can either return the value and assign it to a variable in the calling function like this:
int result = myFunction(someVariable, anotherVariable);
//do stuff with result
Or, use pointers.
I'm not explaining pointers here, that's usually several lectures worth of information, and is one of the more difficult concepts to grasp for introductory programmers. All I can tell you is you need to learn them, but this format is not the right way to go about doing that.
You're passing size to promptData as a copy.
Thus changes to numElem inside promptData will not affect the size variable in your main. Hence size remains uninitialized, i.e. has an undefined value and therefore should not be used as a size for an array.
If you need to initialize an array with a size that's only known at run-time, you need to allocate memory for the array dynamically using malloc, for example:
double* array = malloc(size * sizeof(double));

integer pointer is not initialized

I just installed visual studio 2013 and gonna try a simple code. So I write this one:
int main(void) {
int length = 0;
int *array ;
printf("Enter the number of input: ");
scanf_s("%d", &length);
printf("%d", length);
for (int i = 0; i < length; i++){
scanf_s("%d", array + i);
}
printf("shoting ........ ");
getc;
return 0;
}
When I compile this code, it says local variable "array" is not initialized .
Am I missing something ?
The statement int *array ; declares a pointer. But you don't know where it points to. You can allocate some space using memory allocation functions like malloc() etc. or make it point to some other pre-allocated space. As you are asking user for the input length (i.e. don't know your memory requirement at compile time), dynamic memory allocation like malloc() would be the way to go.
Note: This answer is applicable if you are compiling in C,not C++
int *array;
Declares a pointer of type int*. Since it is not initialized, it points to some random location. This is what the compiler is trying to tell you. Just allocate memory dynamically using malloc. Add
array=malloc(length*sizeof(int));
Just after the first scanf_s to allocate enough memory. Note that you need to include stdlib.h to use malloc.
Also change
getc;
To
getchar();
It is also a good idea to check the return values of malloc,scanf_s etc to see if they are successful.
You need to Initialize the array
such as
int *array = maloc(sizeof(int) * 100);
or
int *array = new int[];

How to expand a one-dimensional array at runtime in C?

I'm learning C language and I have a question about dynamic memory allocation.
Consider that I have a program that the user must enter numbers or typing the letter "E" to exit the program.
The numbers that the user enter must be stored in a one-dimensional array. This array begins with a single position.
How can I do to increase my array of integers to each number that the user enters to store this number in this new position? I think I must use pointers correct? And then, how do I print the values ​​stored in the array?All the examples I find are complex to understand for a beginner. I read about the malloc and realloc functions but I don't know exactly which one to use.
Can anyone help me? Thanks!
void main() {
int numbers[];
do {
allocate memory;
add the number to new position;
} while(user enter a number)
for (first element to last element)
print value;
}
If you need to expand an array at runtime, you must allocate memory dynamically (on the heap). To do so, you can use malloc or more suitable for your situation, realloc.
A good example on this page here, which I think describes what you want.: http://www.cplusplus.com/reference/cstdlib/realloc/
Copy pasted from the link above:
/* realloc example: rememb-o-matic */
#include <stdio.h> /* printf, scanf, puts */
#include <stdlib.h> /* realloc, free, exit, NULL */
int main ()
{
int input,n;
int count = 0;
int* numbers = NULL;
int* more_numbers = NULL;
do {
printf ("Enter an integer value (0 to end): ");
scanf ("%d", &input);
count++;
more_numbers = (int*) realloc (numbers, count * sizeof(int));
if (more_numbers!=NULL) {
numbers=more_numbers;
numbers[count-1]=input;
}
else {
free (numbers);
puts ("Error (re)allocating memory");
exit (1);
}
} while (input!=0);
printf ("Numbers entered: ");
for (n=0;n<count;n++) printf ("%d ",numbers[n]);
free (numbers);
return 0;
}
Note that the size of the array is remembered using countvariable

Resources