How to cycle through array without indexes in C? - c

I need to allocate an N sized array and assign it values, how can I do it without int indexes?
Here is the code I have so far but it doesn't do what I need:
#include <stdlib.h>
#include <stdio.h>
int main() {
int *array;
int n;
printf("Size of array: ");
scanf("%d", &n);
array = (int*) malloc(n*sizeof(int));
if (array == NULL) printf("Memory Fail");
for(; *array; array++)
{
printf("Store:\n");
scanf("%d", &n);
*array = n;
}
for(; *array; array++)
{
printf("Print: %d\n",*array);
}
free(array);
return 0;
}
thanks

for(; *array; array++); you should remove ; at the end
Number of iterations for this loop is undefined and you are going to lose a pointer
You should do something like this:
int *cur;
for(cur = array; cur < array+n; ++cur)
{
*cur = ...;
}

When you allocate the memory, you have no way to determine, in the memory, where it ends (unless you decide a convention and set a value somewhere, but anyway you would use n) .
In your case you have to use n to limit the array coverage (otherwise it is only limited by your computer capacity, and until it reaches an area where it does not have access: program crash). For instance (be careful not to overwrite n !)
int v;
int x = n;
int *ptr = array;
while (x--)
{
printf("Store:\n");
scanf("%d", &v);
*ptr++ = v;
}
x = n;
ptr = array;
while (x--)
{
printf("Print: %d\n",*ptr++);
}

You are using *array as your condition, which means the for loop should continue unless *array evaluates to false, which is only if *array == 0. You are actually invoking undefined behavior because you allocate array with malloc and are trying to dereference the pointer when the underlying data could be anything, since the data block has been uninitialized.
You still need some type of counter to loop with, in this case you allocated n items.
/* I'm using a C99 construct by declaring variables in the for initializer */
for (int i = 0; i < n; ++i)
{
/* In your original code you re-assign your counter 'n', don't do that otherwise you lost the size of your array! */
int temp;
printf("Store: \n");
scanf("%d", &temp)
array[i] = temp;
}
/* This is your second loop which prints the items */
for (int i = 0; i < n; ++i)
{
printf("%d\n", array[i]);
}
Also, do not manipulate the array pointer without keeping a copy of it. You can only do free on the pointer returned by malloc.
Using indexes is the same as manipulating the pointer, your professor is being ridiculous otherwise.

If you have an array int *a; then:
a[0] is equal to *a
a[1] is equal to *(a+1)
a[2] is equal to *(a+2)
So you can go through the array by doing arithmetic on the pointer.

Related

Understanding why it does not find duplicates in array

I wrote the following function in C:
int last(long arr[], int length) {
for (int i = 0; i < length-1; i++)
if (*(arr+i) == *(arr + length - 1))
return 1;
return 0;
}
it checks if the last value of the array was used more than once. In the main:
int *arr = malloc(length*sizeof(int));
for (int i = 0; i < length; i++)
scanf("%d", ++arr);
printf(last((long *) arr, length);
For some reason for the array [1,2,2,3] it returns that the last element was used multiple times and I'm not sure why. I think that is because of scanf("%d", ++arr); but I don't know how to fix it.
My goal is that it will return 1 for [1,3,2,3] and 0 for [1,2,2,3]. What could be the problem?
You should use scanf("%d", &arr[i]);. Using ++arr causes the array to be incremented before you pass it to last, and also reads into data beyond arr, which is undefined behavior.
Another one of the issues in this is the cast to long *.
You should use %ld in scanf and long *arr = malloc(length*sizeof(*arr));.
Also make sure to check for NULL. You never know when malloc is going to fail or someone's going to pass bad data.
Full example:
#include <stdio.h>
#include <stdlib.h>
int last(long arr[], int length) {
if(!arr) return -1;
for (int i = 0; i < length-1; i++)
{
if (arr[i] == arr[length-1])
return 1;
}
return 0;
}
int main(void)
{
long *arr = malloc(4*sizeof(*arr));
if(!arr) return 1;
for (int i = 0; i < 4; i++)
scanf("%ld", &arr[i]);
printf("%d\n", last(arr, 4));
}
Several problems in your code:
Look at this statement:
scanf("%d", ++arr);
^^^^^
In the last iteration of loop, the pointer arr will be pointing to one element past end of array arr (due to pre-increment) and it is is passed to scanf(). The scanf() will access the memory location pointed by the pointer which is an invalid memory because your program does not own it. This is undefined behavior. Note that a pointer may point to one element past the end of array, this is as per standard but dereferencing such pointer will lead to undefined behavior.
Once the main() function for loop finishes the arr pointer pointing to location past the end of memory allocated to arr and just after this you are passing arr to last() function. So, you are passing an invalid memory reference to last() function and then accessing that memory in last() function - one more undefined behavior in your program.
Probably you should take another pointer and point it to arr, so that arr keep pointing to allcoated memory reference returned by malloc().
Note that if you want to read the input the way you are doing then use the post-increment operator in scanf(), like this:
int *arr = malloc(length*sizeof(int));
if (arr == NULL)
exit(EXIT_FAILURE);
int *ptr = arr;
for (int i = 0; i < length; i++)
scanf("%d", ptr++);
but the more appropriate and readable way is - scanf("%d", &arr[i]).
Another big problem in your code is accessing the int values as long type.
The last() function parameter arr type is long and you are passing it int pointer typecasted to long *.
Note that the size of long and int may be different based on the platform. You cannot assume them to be of same size on all platforms.
Assume the case where int size is 4 bytes and long size is 8 bytes.
In this case, when accessing an int pointer using long type pointer then every object will be considered as 8 byte long and when you do arr+1 in last(), the pointer will be advance by 8 bytes and you will never get correct result.
Compiler must be throwing warning message on this statement:
printf(last((long *) arr, length);
because the printf() expects first argument as const char * and you are passing it int (return type of last()). You should give the first argument to printf() a string which contains appropriate format specifier('s).
Putting these altogether:
#include <stdio.h>
#include <stdlib.h>
int last(int arr[], int length) {
if (arr == NULL) {
return 1;
}
for (int i = 0; i < length - 1; i++) {
if (arr[i] == arr[length - 1]) {
return 1;
}
}
return 0;
}
int main(void) {
int length = 4;
int *arr = malloc (length * sizeof (*arr));
if (arr == NULL) {
exit(EXIT_FAILURE);
}
printf ("Enter %d numbers:\n", length);
for (int i = 0; i < length; i++) {
scanf ("%d", &arr[i]);
}
printf ("Duplicate found: %s\n", last (arr, length) == 1 ? "Yes" : "No");
return 0;
}

C function stops after few iterations

The program should do this: write a doubleArray() function, which takes in input an array of int and its size (as a pointer to int). In the main(): ask the user to input an integer n between 1 and 4, then dynamically create an array of size n. Then start filling the array with 2048 randomly generated int: each time the array is full, call the doubleArray function; each time the function doubleArray is called, print the content of the array.
My code works until the size of array n reach a number around 250, then stops inside the for loop.
#include<stdlib.h>
#include<stdio.h>
#include<time.h>
void doubleArray(int vect[], int *dim)
{
int n = *dim *2;
*dim = n;
vect = (int*)realloc(vect, n*sizeof(int));
}
void stampaArray(int vect[], int dim)
{
for (int i=0;i<dim;i++)
{
printf("%d ",vect[i]);
}
printf("\n");
}
int main()
{
printf("Insert a number between 1 and 4: ");
int n;
scanf("%d",&n);
if ((n<1)||(n>4))
{
printf("Number not valid, try again: '");
scanf("%d",&n);
}
int *arr = (int*) malloc (n*sizeof(int));
srand(time(NULL));
int num;
for (int i=0;i<220;i++)
{
num = rand();
if (i==n)
{
doubleArray(arr, &n);
stampaArray(arr, n);
}
arr[i]=num;
}
stampaArray(arr,n);
return 0;
}
Firstly, Change this
if ((n<1)||(n>4)) { } /* use && instead of || to scan if n if both condition are true*/
to
//scanf("%d",&n); /*remove this, use only once, in below loop */
while(1) {
scanf("%d",&n);
if ((n>=1) && (n<=4)) {
break;
}
else {
printf("Number not valid, try again: '");
}
}
And allocate memory equal to n bytes. for e.g
int *arr = malloc (n * sizeof(*arr)); /* typecasting is not required */
Also here
for (int i=0;i<220;i++) { /* some code */ }
what is the rationale behind rotating loop 220 times, doesn't it should be n times ?
As you were said in comment, your main error is that realloc is allowed to change the pointer value. If it happens, the new value is only assigned to the local copy inside the doubleArray function, but the caller still keeps the previous value which is now a dangling pointer (pointing to non allocated memory). Using it invokes Undefined Behaviour (and crashes are to be expected...)
The correct way is to return the new pointer value:
int * doubleArray(int vect[], int *dim)
{
int n = *dim *2;
*dim = n;
return realloc(vect, n*sizeof(int));
}
That is not all. best practices recommend to test allocation. In a stressed environment, the system could be unable to allocate enough memory and realloc could return NULL. Proceeding would then also involve Undefined Behaviour.
Let us go on. Controlling input is nice, but a user can type twice an error, so you should loop until you get a correct value:
int n;
for (;;) {
printf("Insert a number between 1 and 4: ");
scanf("%d",&n);
if ((n >= 1) && (n <= 4)) break;
printf("Number not valid, try again: '");
}
And please, please do not cast malloc in C language. It is useless and can hide hard to find indirection level errors.
Finally, I cannot understand why you have a loop up to 220... From your requirements it should be up to 2048.
Last point (but this one is only my opinion, not a problem): I would only display the initialized content of the array, so up to i instead of n. That way you would see the array grow while always keeping the same (initialized) values:
int *arr = malloc (n*sizeof(int));
srand(time(NULL));
int num;
for (int i=0;i<2048;i++)
{
num = rand();
if (i==n)
{
arr = doubleArray(arr, &n);
if (arr == NULL) {
perror("allocation error");
return 1;
}
stampaArray(arr, i);
printf("\n");
}
arr[i]=num;
}
stampaArray(arr,2048);
free(arr); // not required immediately before a return but good practice

sprintf Producing segmentation fault

I am getting a segmentation fault from the below program.
#include <stdio.h>
#include <string.h>
void removeProcess(int*, int);
void removeProcessN(char**, int, int);
void main() {
int numPro = 0, quanTime = 0, contTime = 0, i, elemNum, time = 0;
//Supply variables with user input
printf("Enter number of processes: ");
scanf("%d", &numPro);
printf("Enter context switch time: ");
scanf("%d", &contTime);
printf("Enter quantum of time: ");
scanf("%d", &quanTime);
//Create array of number of process time
int proTime[numPro];
//Create string array for better output
char *proNames[numPro];
//Retrieves process time from user
for (i = 0; i < numPro; i++){
printf("Enter execution time for process %d: ", i);
scanf("%d", proTime + i);
sprintf(proNames[i], "p%d", i);
}
elemNum = 0;
//While a process remains active
while (numPro != 0) {
//Retrieves the element being worked with
elemNum = elemNum % numPro;
//Describe process working with
printf("Executing process %s\nStart time = %d\n", proNames[elemNum], time);
proTime[elemNum] -= quanTime;
//If process time complete, remove process
if (proTime[elemNum] <= 0){
removeProcess(proTime, elemNum);
removeProcessN(proNames, elemNum, numPro);
--numPro;
}
//Add amount of time with context time
time = time + quanTime + contTime;
elemNum++;
}
}
/**
*#param *array pointer to an array of integers
*#param elem int of the element to remove
* Removes an element 'elem' from the supplied integer array.
*/
void removeProcessN(char **array, int numElem, int elem) {
char *temparray[numElem - 1];
//Copy array to temparray except for elem to remove
int i;
for (i = 0; i < elem; i++) {
if (i == numElem) {
continue;
} else {
temparray[i] = array[i];
}
}
//End by setting the pointer of array to the temparray
array = temparray;
}
/**
*#param *array pointer to an array of integers
*#param elem int of the element to remove
* Removes an element 'elem' from the supplied integer array.
*/
void removeProcess(int *array, int elem) {
//Number of elements in the array
int numElem = sizeof(array) / sizeof(int);
int temparray[numElem - 1];
//Copy array to temparray except for elem to remove
int i;
for (i = 0; i < numElem; i++) {
if (i == elem) {
continue;
} else {
temparray[i] = array[i];
}
}
//End by setting the pointer of array to the temparray
array = temparray;
}
I know the segmentation fault is coming from sprintf. I am trying to simulate how an operating system would complete a process using round robin. I have tried using sprintf because that's what tutorials were saying online to use when trying to manipulate strings. The removeProcessN is just removing an index from the array proNames. I am mostly just concerned with the sprintf.
I have tried malloc when I do the sprintf but it would not even compile at that point. If someone could offer an explanation I'd be appreciative.
The problem here is that proNames is an array of pointers, but they are
uninitialized, so passing it to sprintf to write something, will crash. You
would have either use a double array or allocate memory with malloc. But as
you are only printing integers and the string representatuion of integers has a
maximal length, allocating memory with malloc will be more harder, because you
have to check that malloc doesn't return NULL, you have to free the memory
later, etc.
So I'd do:
char proNames[numPro][30]; // 28 characters for an int (usually 4 bytes long)
// should be more than enough
//Retrieves process time from user
for (i = 0; i < numPro; i++){
printf("Enter execution time for process %d: ", i);
scanf("%d", proTime + i);
sprintf(proNames[i], "p%d", i);
}
Your removeProcessN would need to change as well:
void removeProcessN(int numElem, int elem, int dim, char (*array)[dim]) {
for(int i = elem; i < numElem - 1; ++i)
strcpy(array[i], array[i+1]);
array[numElem - 1][0] = 0; // setting last element to empty string
}
Note that I moved the array argument at the last position, otherwise numElem
is not known and the compiler would return an error.
And now you can call it like this:
removeProcessN(elemNum, numPro, 30, proNames);
The 30 comes from the char proNames[numProp][30]; declaration.
I'd like to comment on the last line of your function removeProcessN:
//End by setting the pointer of array to the temparray
array = temparray;
That is not correct, first because temparray is local variable and ceases to
exist when the function returns. And array is local variable in the function,
so changing it doesn't affect anybody.
The alternative with memory allocation would look like this:
char *proNames[numPro];
//Retrieves process time from user
for (i = 0; i < numPro; i++){
printf("Enter execution time for process %d: ", i);
scanf("%d", proTime + i);
int len = snprintf(NULL, 0, "p%d", i);
proNames[i] = malloc(len + 1);
if(proNames[i] == NULL)
{
// error handling, free the previously allocated
// memory, and return/exit
}
sprintf(proNames[i], "p%d", i);
}
and removeProcessN:
void removeProcessN(char **array, int numElem, int elem) {
char *to_remove = array[elem];
for(int i = elem; i < numElem - 1; ++i)
array[i] = array[i+1];
free(to_remove);
array[numElem - 1] = NULL; // setting last element to NULL
// makes freeing easier as
// free(NULL) is allowed
}
And the way you originally called the removeProcessN would be OK.
If you eventually call removeProcessN for all processes, then all the memory
should be freed because removeProcessN frees it. If there are some elements
that remain in the array, then you have to free them later.
OP posted in the comments
My theory was that temparray would be a pointer to an array so I could just remove an index from the main array.
So when I say array = temparray, the pointer for array points to temparray. I know it worked for removeProcess. Is it different for strings?
The array = temparray also has no effect in removeProcess, array is still
a local variable and changing where it points to has no effect at all, because
you are changing a local variable only.
Besides the code is wrong:
int numElem = sizeof(array) / sizeof(int);
this only works for pure arrays, it does not work for pointers because
sizeof(array) returns you the size that a pointer of int needs to be stored.
Like the other function, you need to pass the site the array to the function.
If you say that this function worked, then just only by accident, because it
yields undefined behavior. By incorrectly calculating the number of elements,
temparray will have the wrong size, so here temparray[i] = array[i]; you may
access beyond the bounds which leads to undefined behaviour. Undefined behaviour
means that you cannot predict what is going to happen, it could be anything from
crashing to formatting your hard drive. Results that result from undefined
behaviour are useless.
And again array = temparray; just changes where the local variable array is
pointing, the caller of removeProcess doesn't see that.
The correct version would be:
int removeProcess(int *array, int elem, int numElem) {
if(array == NULL)
return 0;
// nothing to do if the elemnt to be removed is
// the last one
if(elem == numElem - 1)
return 1;
// overwriting the memory, because memory
// regions overlap, we use memmove
memmove(array + elem, array + elem + 1, numElem - elem - 1);
return 0;
}
So, to make it clear:
Let's look at this code:
void sum(int *array, size_t len);
{
int c[len];
array = c;
}
void bar(void)
{
int x[] = { 1, 3, 5 };
size_t len = sizeof x / sizeof *x;
sum(x, sizeof x / sizeof *x);
printf("x[0] = %d, x[1] = %d, x[2] = %d\n", x[0], x[1], x[2]);
}
sum has only a copy of the pointer you've passed in bar, so from bar's
point of view, sum changed the copy, so bar will print
x[0] = 1, x[1] = 3, x[2] = 5.
But if you want that the caller sees any change, then you to access through the
pointer:
void sum(int *array, size_t len)
{
int c[len];
for(size_t i = 0; i < len; ++i)
array[i] += 10;
array = c;
}
With this version bar would print x[0] = 11, x[1] = 13, x[2] = 15 and
and array = c will have no effect on bar.

dynamically increase size of array (int*) in c

i want to dynamically add numbers to an array in c. My idea is to just allocate a new array with size + 1, add the number, free the root array and change the pointer from the temp to the root array. Like this:
void addNumber(int* a, int* size, int number)
{
*size = *size + 1;
int* temp = (int*)(calloc(*size, sizeof(int)));
int i, j = 0;
for(i = 0; i < *size-1; i++) {
if(a[i] < number) {
printf("add ai");
temp[j] = a[i];
j++;
} else {
printf("add number");
temp[j] = number;
}
}
if(j != *size) {
printf("add new number");
temp[j] = number;
}
free(a);
a = temp;
}
int main(int argc, char* argv[])
{
int n = 10;
int* a;
int size = 1;
a = (int*) (calloc(1, sizeof(int)));
a[0] = 1;
if(!contains(a, size, 2)) {
addNumber(a, &size, 2);
}
printArray(a,size);
return 0;
}
The problem is that in the addNumber function the code works and the *a has the right values of the new array. But in the main function the array *a has the values 1,0. So the new inserted value 2 is not added. Why? Can't get the reason.
To dynamically change the array size, you can use the realloc() routine. Apart from being eaiser to use, it can be faster than the approach of calling free() and malloc() sequentially.
It is guaranteed the reallocated block will be populated with the content of the old memory block.
The problem is that in the addNumber function the code works and the *a has the right values of the new array
There are two major flaws in your code. The first is that you your addNumber() routine doesn't return the newly allocated memory block (thus it is being leaked), you should either use double pointer or return the new block as function result.
And the second one results from the first - after a has been freed, you continue to write to it.
If you prefer to stick to your current approach, this modified code should work:
void addNumber(int** a, int* size, int number)
{
*size = *size + 1;
int* temp = (int*)(calloc(*size, sizeof(int)));
int i, j = 0;
for(i = 0; i < *size-1; i++) {
if((*a)[i] < number) {
printf("add ai");
temp[j] = (*a)[i];
j++;
} else {
printf("add number");
temp[j] = number;
}
}
if(j != *size) {
printf("add new number");
temp[j] = number;
}
free(*a);
*a = temp;
}
int main(int argc, char* argv[])
{
int n = 10;
int* a;
int size = 1;
a = (int*) (calloc(1, sizeof(int)));
a[0] = 1;
if(!contains(a, size, 2)) {
addNumber(&a, &size, 2);
}
printArray(a,size);
return 0;
}
What you're looking for is realloc(). It can be used to grow or shrink memory while retaining its contents.
/* array is now sizeof(int) * new_size bytes */
array = realloc(array, sizeof(int) * new_size);
realloc() might change the existing memory allocation, or it might allocate a whole new block of memory. This is why it's important to reassign the result back to the thing being reallocated.
But if addNumber() reallocates the array by making new memory, main() won't know it. This is for the same reason this doesn't work.
void incrementNumber(int num) {
num = num + 1;
}
int num is a number that gets passed by value. If you want it to be reflected in the caller, you need to pass it as a pointer.
void incrementNumber(int *num) {
*num = *num + 1;
}
Pointers are the same way. They're still numbers. int *a passes a pointer by value. If you change a in addNumber it won't be seen by the caller. Just like before, you need to pass it as a pointer. A pointer to a pointer used like this is known as a double pointer.
void addNumber( int **array_ptr, size_t *array_size, size_t type_size, int number ) {
/* Increment the size and make sure that bubbles up */
*array_size = *array_size + 1;
/* realloc might grow the memory, or it might allocate new memory
either way, assign the result back to its original variable
by dereferencing the double pointer.
*/
*array_ptr = realloc(*array_ptr, *array_size * type_size);
/* Since it's a double pointer, we have to first dereference it before using
it as an array */
(*array_ptr)[*array_size - 1] = number;
}
(Note that I also pass in the sizeof the elements in the array, that can't be assumed).
This is called by passing a pointer to the array.
addNumber(&a, &size, sizeof(int), 5);
After that, everything is the same.
for( int i = 0; i < size; i++ ) {
printf("%d ", a[i]);
}
puts("");
Eventually you'll want to improve this by having the array, size, and type in a struct so you can pass that around in a neat package.
typedef struct {
int *array;
size_t size;
} IntArray;
This is great to do as an exercise, you'll learn a lot and kick a lot of bad habits about static memory. But doing dynamic data structures correctly and efficiently is difficult (for example, allocating one extra slot at a time is very inefficient).
There are many, many libraries out there which provide such dynamic structures. So continue with this as an exercise, but for real code use a library such as Gnome Lib.
Why? Can't get the reason.
That's because you are modifying the value of a locally in addNumber. That does not change the value of a in main.
In order for main to have access to the newly allocated memory, you need to change addNumber to return the newly allocated pointer.
int* addNumber(int* a, int* size, int number){
...
return a;
}
and then change main to:
if(!contains(a, size, 2)){
a = addNumber(a, &size, 2);
// Assign to a the new pointer value.
}
Your 'a' in main is already a pointer, passing it to a function passes a copy of it. What you have to do is - pass the adress '&a' and receive it in funtion as double pointer '**a' and inside the function, use dereference to get values inside array ( like *a[i] and free(*a).
Change the last line to 'return temp' and collect it in main as a=addnumber(&a,&size,2);
By the way, instead of going through all these hassle why don't you just use realloc() function. It increases the size of array dynamically. After using realloc you can just add the new number at the last index.

Initialising an int array in an if statement and using externally

New to C here and would appreciate if I could get some pointers.
I'm trying to initialise an array inside an if statement, and then print the values of the array externally - but I know the scope will be lost after the if block ends. I've tried creating the array with pointers. The reason I'm doing it inside the if statement is because the size of the array depends on a value calculated during runtime.
E.g.:
void createArray() {
int userInput;
printf("%s\n", "Please enter a value:");
scanf("%d\n", userInput);
if (userInput > 10) {
int array[userInput];
}
int i;
for (i = 0; i < userInput; i++) {
array[i] = i;
}
}
int i;
for (i = 0; i < sizeof(array)/sizeof(array[0]); i++) {
printf("%d\n", array[i]);
}
However because the array is declared inside a method, I obviously lose scope of it when it comes to the final for loop to print - thus an error occurs. I've tried creating a pointer variable int *array as a global variable, and inside the if statement, just staying array = int[10] but obviously this won't work.
This isn't my exact code, I've recreated a minimal example that shows my error so some syntax may be wrong here - apologies for that.
Any help would be appreciated.
One question you have to consider in your code is what happens if userInput is less than or equal to 10? You iterate over userInput elements of an array that was not declared.
One simple way of handling this is to make a large array at the beginning of your function and then use just the first userInput elements of it. This approach has obviously its limitations (e.g. userInput can't be larger than the size of the array, and you should make sure it won't be, otherwise bad things may happen), but is simple.
Another approach involves using dynamic memory allocation. This is done by using the malloc function:
int *array = malloc(100 * sizeof(int));
The code above allocates memory for 100 ints, basically creating an array of 100 elements. Then, you can use the array as usual. But, make sure you free it after you're done:
free(array);
Note that using this approach you'd need to declare the pointer first:
int *array;
if (userInput > 10) {
array = malloc(userInput * sizeof(int));
}
Below you can find a small proof of concept program. Note that instead of a global variable, the pointer value can be returned from the alloc function.
#include <stdio.h>
#include <stdlib.h>
int *arr;
void alloc() {
arr = malloc(10 * sizeof(int));
}
void assign() {
for (int i = 0; i < 10; i++)
arr[i] = i + i;
}
void print() {
for (int i = 0; i < 10; i++)
printf("%d\n", arr[i]);
}
int main(int argc, char *argv[])
{
alloc();
assign();
print();
free(arr);
return 0;
}
This allocates an array of int to the pointer intary. The pointer may be passed to other functions from main(). In main, userInput stores the number of int allocated.
#include <stdio.h>
#include <stdlib.h>
int *createArray( int *userInput);
int main( int argc, char *argv[])
{
int i;
int userInput = 0;
int *intary = NULL;
if ( ( intary = createArray ( &userInput)) != NULL ) {
for (i = 0; i < userInput; i++) {
intary[i] = i;
printf ( "%d\n", intary[i]);
}
free ( intary);
}
return 0;
}
int *createArray( int *userInput) {
int *array = NULL;
printf("%s\n", "Please enter a value:");
scanf("%d", userInput);
if ( *userInput > 10) {
if ( ( array = malloc ( *userInput * sizeof ( int))) == NULL) {
printf ( "could not allocate memory\n");
*userInput = 0;
return NULL;
}
}
else {
*userInput = 0;
return NULL;
}
return array;
}
You don't need some pointers, just one, (int* arr) and malloc(),a dynamic memory allocation function.
Note: You shouldn't use "array" as a variable name as it may create problems. So we'll name our variable arr.
If you're unfamiliar with it, i will explain the code too.
First add #include <stdlib.h> header file, which contains malloc().
Then declare a pointer of type int int* arr, we have named it arr in the createArray() scope.
We'll allocate the space required in the if condition with malloc() function, like :
void createArray() {
int userInput;
int* arr; // declare arr pointer
printf("%s\n", "Please enter a value:");
scanf("%d\n", userInput);
if (userInput > 10) {
arr = (int*) malloc ( userInput * sizeof(int) ); // explained below
}
int i;
for (i = 0; i < userInput; i++) {
arr[i] = i;
}
}
free(arr) // don't forget to free after using
[NOTE] This code is untested.
arr = (int*) malloc ( userInput * sizeof(int) );
This line may seem cryptic at first, but what it does is pretty simple , it allocates some memory dynamically on the heap.
The size of this memory is given by 'userInput * sizeof(int)', sizeof() function specifies the size of int on the given machine multiplied by userInput by the user,
Then, it is typecasted to int* type so that we can store the address in our int* type pointer arr.
[UPDATE] you can use arr = malloc ( userInput * sizeof(int) ); instead as suggested in comments, here is why Do I cast the result of malloc?

Resources