How to use pointers to allocate an array inside another function - c

I'm 2nd year computer engineer and still in learning process of C language. I'd like to undesrtand how to dynamically alocate an array by using function instead of allocate inside the main.
Here is the code that works when I allocate array inside main.
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <time.h>
#define ESC_KEY 27
#define NUM_1_KEY 49
#define NUM_2_KEY 50
void find_two_largest(int a[], int n, int *largest, int *second_largest);
void arrayInit(int *,int *, int, int);
void randGenArray(int [], int);
void inputArray(int[], int);
void result(int, int);
void loading(void);
int menu(void);
int main(void)
{
system("color f5");
int n,i,largest,largest_2, *a;
arrayInit(a,&n, 2, 10);
if(menu())
randGenArray(a,n);
else
inputArray(a,n);
find_two_largest(a,n,&largest,&largest_2);
result(largest,largest_2);
return 0;
}
void find_two_largest(int a[], int n, int *largest, int *second_largest)
{
int i=0,j=0;
system("cls");
loading();
*largest = 0;
*second_largest = *largest;
for (i=1;i<n;i++){
if(*largest<a[i])
*largest=a[i];
}
for(j=1;j<n;j++){
if(*largest==a[j])
continue;
else{
if(*second_largest<a[j])
*second_largest=a[j];
}
}
return;
}
void randGenArray(int a[], int n)
{
srand(time(NULL));
int i;
for(i=0; i<n; i++){
a[i]=rand()%100;
Sleep(10);
printf("\n>> Integer %d: %d", i+1, a[i]);
}
printf("\n\n\nPress any key to continue...");
getch();
return;
}
void inputArray(int a[], int n)
{
int i;
for(i=0; i<n; i++){
printf("\n Please enter integer %d: ", i+1);
scanf("%d",&a[i]);
}
return;
}
int menu(void)
{
char _char;
printf("\n Please choose one of the following options:\n 1.Fill array manually\n 2.Fill array by random numbers\n\n ");
while(1)
{
_char = getch();
switch(_char)
{
case ESC_KEY:
printf("\n\n Thank you for using our software!\n\n");
exit(0);
case NUM_1_KEY:
system("cls");
return 0;
case NUM_2_KEY:
system("cls");
return 1;
default:
break;
}
}
}
void arrayInit(int *a,int *n, int min, int max)
{
printf("\n Please enter a length of the array: ");
do{
scanf("%d", n);
if (*n<min||*n>max)
printf("\nThe ranged is limited. Please enter the value between %d and %d.\n", min, max);
} while(*n<min||*n>max);
a = (int*)calloc(*n,sizeof(int));
return;
}
void loading(void)
{
printf("\n Loading");
printf(".");
Sleep(300);
printf(".");
Sleep(300);
printf(".");
Sleep(300);
system("cls");
return;
}
void result(int l, int l2)
{
system("cls");
printf("\n Largest = %d Second Largest = %d",l,l2);
Sleep(500);
printf("\n\n\n Thank you using our software! ;D\n\n");
return;
}
But if you cut and paste this line from arrayInit to main and change *n to n - it will work!
a = (int*)calloc(*n,sizeof(int));
I'm sorry for asking about so stupid and obvious things but I didn't figure it out by myself. Thank you for any advice.

Here is a simple program which will show you how to do that -
#include <stdio.h>
#include <stdlib.h>
void create(int **p,int n); // function taking arguments as int ** and n is number of elements
int main(void) {
int *a;
int n=5,i; // declare and initialize n
create(&a,n); // pass address of a to function
for(i=0;i<n;i++){
a[i]=i; // store value of i in a[i]
printf("%d\n",i); // print a[i]
}
free(a); // free the allocated memory
return 0;
}
void create(int **p, int n){
*p=calloc(n,sizeof(int)); // allocate memory to *p (type- is int *)
}
Working Code

You must change your function return type
void * arrayInit(int *n, int min, int max)
{
printf("\n Please enter a length of the array: ");
do{
scanf("%d", n);
if (*n<min||*n>max)
printf("\nThe ranged is limited. Please enter the value between %d and %d.\n", min, max);
} while(*n<min||*n>max);
return calloc(*n,sizeof(int));
}
And call it from main in this way: a = arrayInit(&n, 2, 10);

Related

Calling one function inside another, does not execute as desired

Since I've had several members tell me to post the whole program I'm gonna post the whole program so you can exectue it.
In this program I want to be able to register car parts and change the inventory balance.
Now to the issue. Every function itself worsk well, the problem starts when I call searchIt() function to changeIn() function. I need searchIt() so I can search the item before modifying its inventory balance.
Issues:
Whenever I serach for an item and change inventory on that item, it changes on every item.
In menu if I choose (3)change inventory balance and then serach for an item that does not exist it does not tell me "Wrong item number" instead it exits the program.
The inventory balance goes to negative numbers.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXELENGTH 20
#define MAX 100
struct car{
int itemNmr;
char name[MAXELENGTH];
int inventory;
};
typedef struct car Car;
void registerArticle(Car a[], int *pN);
void print(Car a[], int n);
void changeIn(Car a[], int n);
int searchIt(Car a[], int n);
Car createIt(int itemNmr, char name[],int inventory){
Car c;
c.itemNmr = itemNmr;
strcpy(c.name, name);
c.inventory = inventory;
return c;
}
int main(){
Car reg[MAX];
int choice;
int nrOfIt=0;
while(1){
printf("(1)Register new pars\n(2)Display all parts\n(3)Change inventory\n(4)Search\n(5)Exit\n");
scanf("%d", &choice);
switch(choice){
case 1: registerArticle(reg, &nrOfIt);
break;
case 2: print(reg,nrOfIt);
break;
case 3: changeIn(reg,nrOfIt);
break;
case 4: searchIt(reg,nrOfIt);
break;
case 5: printf("Exit");
return 0;
default: printf("Try again!");
break;
}
} return 0;
}
void registerArticle(Car a[], int *pN){
int inventory;
int itemNmr;
char name[MAXELENGTH];
while(1){
printf("Item number(0 to exit): ");
scanf("%d%*c", &itemNmr);
if(itemNmr==0){
return;
}
printf("Name: ");
scanf("%s%*c", name);
printf("Inventory: ");
scanf("%d%*c", &inventory);
a[*pN]=createIt(itemNmr,name,inventory);
(*pN)++;
}
}
void print(Car a[], int n){
if(n==0){
printf("the list is empty\n");
}else{
for(int i=0;i<n;i++){
printf("%d\t\t%s\t\t%d\n", a[i].itemNmr, a[i].name, a[i].inventory);
}
return;
}
}
int searchIt(Car a[], int n){
while(1){
int itemN;
printf("Type item number: ");
scanf("%d", &itemN);
if(itemN==0){
break;
}
int found =0;
for(int i=0;i<n;++i)
{
if(itemN==a[i].itemNmr)
{
printf("%d\t\t%s\t\t%d\n", a[i].itemNmr, a[i].name, a[i].inventory);
return i;
break;
}
}
if(!found)
{
printf("Wrong item number!");
}
}
return 0;
}
void changeIn(Car a[], int n){
int input;
int i;
searchIt(a,i);
printf("Increase or decrease by: ");
scanf("%d", &input);
for(i=0;i<n;i++)
a[i].inventory += input;
if(a[i].inventory<0)
a[i].inventory = 0;
}
```
This:
void changeIn(Car a[], int n)
{
int input;
int i;
searchIt(a, i);
passes an uninitialized register-length to searchIt(), probably causing it to go way out of bounds. Then it throws away the return value of searchIt(), and then uses the still uninitialized i to index into the array. Not good. It should be:
void changeIn(Car a[], int n)
{
int input;
const int i = searchIt(a, n);
Edit:
As you pointed out in a comment, yes the loop in changeIt() makes no sense; you don't want to change more than one element so there is no need to loop. Looping is for expressing repetition and there's no need for that here.
It should just be:
a[i].inventory += input;
if (a[i].inventory < 0)
a[i].inventory = 0;

Can someone tell me why am i getting this error?

I wrote a program that has a menu. First is double the space of the table, second minimize the space of the table by half, etc. Here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void double_space(int *table, int *n);
void half_space(int *table, int *n);
void fill(int *table, int n, int start, int finish);
void main()
{
int N = 4;
int *t;
int i, choice;
t = (int *)malloc(N*sizeof(int));
if(t == NULL)
{
printf("Unable to allocate memory...");
exit(0);
}
for (i=0; i<N; i++)
{
t[i] = i;
}
while (1)
{
printf("\tMENU\n");
printf("1) Double the size of table\n");
printf("2) Minimize the size of table\n");
printf("3) Print table\n");
printf("4) Exit the program\n");
printf("Choose one of the above: ");
scanf("%d", &choice);
switch (choice)
{
case 1:
double_space(t, &N);
fill(t, N, N/2, N-1);
printf("\nTable is double in size");
break;
case 2:
half_space(t, &N);
fill(t, N, N/2, N-1);
printf("\nTable is half in size");
break;
case 3:
for (i=0; i<N; i++)
{
printf("%d ", t[i]);
}
printf("\n");
break;
case 4:
exit(0);
default:
printf("Invalid choice...");
break;
}
}
}
void double_space(int *table, int *n)
{
*n = (*n)*2;
table = (int *)realloc(table, *n);
if(table == NULL)
{
printf("Unable to allocate memory...");
exit(0);
}
}
void half_space(int *table, int *n)
{
*n = (*n) / 2;
table = (int *)realloc(table, *n);
if(table == NULL)
{
printf("Error allocating memory...");
exit(0);
}
}
void fill(int *table, int n, int start, int finish)
{
int i;
if(start>=0 && start<=finish && finish<=n-1)
{
srand(time(NULL));
for (i=start; i<=finish; i++)
{
table[i] = rand() % 100;
}
}
}
After choosing the First choice and then the 3rd choice to print the table it prints the doubled size table. Then when i choose again the 1st choice it outputs this error:
realloc(): invalid next size
Aborted (core dumped)

scanf not passing value to variable

I wanted to ask a little bit about scanf in C using Xcode IDE. If I not initially set value for variable choice, anytime I open my program and enter any choice(either 1/2) it will go to else case every time. So I check the value after select any choice then I got a strange number. Could you please take a look at my code. Thank you in advance.
Here's my actual code:
/* Bubble Sort using MPI */
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
#include <time.h>
#define N 1000
double startT,stopT;
double startTime;
void showElapsed(int id, char *m)
{
printf("%d: %s %f secs\n",id,m,(clock()-startTime)/CLOCKS_PER_SEC);
}
void showVector(int *v, int n, int id)
{
int i;
printf("%d: ",id);
for(i=0;i<n;i++)
printf("%d ",v[i]);
putchar('\n');
}
int * merge(int *v1, int n1, int *v2, int n2)
{
int i,j,k;
int * result;
result = (int *)malloc((n1+n2)*sizeof(int));
/*
i : pointer of v1
j : pointer of v2
k : pointer of k
*/
i=0; j=0; k=0;
while(i<n1 && j<n2)
if(v1[i]<v2[j])
{
result[k] = v1[i];
i++; k++;
}
else
{
result[k] = v2[j];
j++; k++;
}
if(i==n1)
while(j<n2)
{
result[k] = v2[j];
j++; k++;
}
else
while(i<n1)
{
result[k] = v1[i];
i++; k++;
}
return result;
}
void swap(int *v, int i, int j)
{
int t;
t = v[i];
v[i] = v[j];
v[j] = t;
}
void sort(int *v, int n)
{
int i,j;
for(i=n-2;i>=0;i--)
for(j=0;j<=i;j++)
if(v[j]>v[j+1])
swap(v,j,j+1);
}
int main(int argc, char **argv)
{
int * data;
int * chunk;
int * other;
int m,n=N;
int id,p;
int s;
int i;
int step;
int choice = 0;
//start asking user to select option between sequential or parallel version of BubbleSort
printf(":: Welcome to BubbleSort Project for CSS333 ::\n");
printf("Please select option that you prefer\n");
printf("Type \"1\" for sequential mode or \"2\" for parallel mode\n");
printf("");
fflush(stdout);
scanf("Enter here: %d", &choice);
printf("Test value of choice(should be either 1 or 2): %d\n", choice);
//end asking
if(choice == 1){
// do seq
printf("You have selected option 1 which is running BubbleSort in Sequential mode\n");
printf("Please wait...");
}
else if(choice == 2){
// do parallel
printf("You have selected option 2 which is running BubbleSort in parallel mode\n");
printf("Please wait...");
MPI_Status status;
MPI_Init(&argc,&argv);
MPI_Comm_rank(MPI_COMM_WORLD,&id);
MPI_Comm_size(MPI_COMM_WORLD,&p);
if(id==0)
{
int r;
srandom(clock());
s = n/p;
r = n%p;
data = (int *)malloc((n+p-r)*sizeof(int));
for(i=0;i<n;i++)
data[i] = random();
if(r!=0)
{
for(i=n;i<n+p-r;i++)
data[i]=0;
s=s+1;
}
startT = clock();
MPI_Bcast(&s,1,MPI_INT,0,MPI_COMM_WORLD);
chunk = (int *)malloc(s*sizeof(int));
MPI_Scatter(data,s,MPI_INT,chunk,s,MPI_INT,0,MPI_COMM_WORLD);
sort(chunk,s);
}
else
{
MPI_Bcast(&s,1,MPI_INT,0,MPI_COMM_WORLD);
chunk = (int *)malloc(s*sizeof(int));
MPI_Scatter(&data,s,MPI_INT,chunk,s,MPI_INT,0,MPI_COMM_WORLD);
sort(chunk,s);
}
step = 1;
while(step<p)
{
if(id%(2*step)==0)
{
if(id+step<p)
{
MPI_Recv(&m,1,MPI_INT,id+step,0,MPI_COMM_WORLD,&status);
other = (int *)malloc(m*sizeof(int));
MPI_Recv(other,m,MPI_INT,id+step,0,MPI_COMM_WORLD,&status);
chunk = merge(chunk,s,other,m);
s = s+m;
}
}
else
{
int near = id-step;
MPI_Send(&s,1,MPI_INT,near,0,MPI_COMM_WORLD);
MPI_Send(chunk,s,MPI_INT,near,0,MPI_COMM_WORLD);
break;
}
step = step*2;
}
if(id==0)
{
FILE * fout;
stopT = clock();
printf("%d; %d processors; %f secs\n",N,p,(stopT-startT)/CLOCKS_PER_SEC);
fout = fopen("result","w");
for(i=0;i<s;i++)
if (chunk[i] != 0)
fprintf(fout,"%d\n",chunk[i]);
fclose(fout);
}
MPI_Finalize();
}
else{
printf("Invalid value\n");
printf("Program exiting...\n");
exit(0);
}
}
This is your problem:
scanf("Enter here: %d", &choice);
You might be expecting this to display "Enter here: " then accept a number as input and store it in the variable choice. But that's not what it does.
What this does is that it goes through the formatting string ("Enter here: %d"), one character by one. For each character that is not '%', it reads a character from stdin and compares them together. If they don't match, it pushes the character back to the buffer of stdin and stops scanning.
So unless the user types in something starting with Enter here: followed immediately by a number, it fails at reading that number.
What you probably wanted to do is to:
printf("Enter here: ");
scanf("%d", &choice);
(and then read the documentation for scanf().

Insert and delete in a Heap in c

I have a problem in my program which should prompt the user to enter number and the program will heapify them. The program runs but shows a runtime error after inserting the first number.
I tried to fix it multiple times but in vain.
If anyone could point to the precise error in the code it would be much appreciated. Thanks in advance. =)
Anyways, here's the code:
#include <stdio.h>
void insert_node(int arr[], int max){
if(max<15){
printf("Type the number to insert: ");
scanf("%d", arr[max]);
max++;
}
else
printf("Error. The heap is full!");
}
void printheap(int arr[], int max){
int count;
if(max>=1){
printf("\nPrinting the Heap:");
for(count==0;count<=max;count++)
printf(" %d", arr[count]);
}
}
void heapSort(int arr[], int max) {
int i=0,temp,lc,rc;
while(i!=max-1){
lc=2i+1;
rc=2i+2;
if(arr[i]<arr[lc]){
temp=arr[i];
arr[i]=arr[lc];
arr[lc]=temp;
}
else if(arr[i]<arr[rc]){
temp=arr[i];
arr[i]=arr[rc];
arr[rc]=temp;
}
i=i+1;
}
}
int main(int argc, char *argv[]){
int arr[15];
int max=0;
char ch;
while(ch!='n' && ch!='N'){
printheap(arr,max);
insert_node(arr,max);
if(max>1)
heapSort(arr,max);
printf("\nInsert another key (y:yes/n:no)? ");
scanf("%c", &ch);
}
return 0;
}

Making arrays user input specific for bubble sort?

I'm learning to how to use command line arguments to get a number to decide how many elements are in an array to organize. The random number generator is supposed to take the user's number and generate that many random numbers, then sort them with the bubble sort.
But the number cannot be less than 2 or greater than 10,000.
I keep getting Segmentation fault (core dumped) or I'm able to enter any number (including a number less than 2 or greater than 10,000) and it does nothing.
I'm sure it is the first part of the code that is wrong, not the subprograms and definitions, but I don't know how to fix it.
#include <stdio.h>
int randu(void);
void bubble(int *, int);
void swap(int *, int *);
int main(int argc, char *argv[]) {
int num1;
if (argc<2) {
printf("Number must be between 2 and 10000.\n");
printf("Enter a number to sort.\n");
scanf("%d", &num1);
}
if (argc>10000) {
printf("Number must be between 2 and 10000.\n");
printf("Enter a number to sort.\n");
scanf("%d", &num1);
}
sscanf(argv[1], "%d", &num1);
int main(void) {
int x[num1], i;
for(i=0;i<num1;i++)
x[i]=randu();
printf("Here are %d numbers\n", num1);
for (i=0;i<num1;i++)
printf("%d\n",x[i]);
}
}
int randu(void) {
static int seed=17;
seed=(25179*seed+13849)%65536;
return seed;
}
void bubble(int a[], int num1){
int i,j;
for (i=0;i<num1-1;i++)
for(j=num1-1;i<j;j--)
if(a[j-1]>a[j])
swap(&a[j-1],&a[j]);
}
void swap(int *a, int *b){
int temp;
temp=*a;
*a=*b;
*b=temp;
}
There are a number of issues with your code
1) The use of argc is wrong. argc is not the value of an argument. It is the number of arguments (including program name).
2) There is a nested main inside main. Don't do that.
3) You never call the bubble sort function. Add it.
So a minor rewrite of your program:
int randu(void);
void bubble(int *, int);
void swap(int *, int *);
int main(int argc, char *argv[]) {
int num1;
if ((argc < 2) ||
(sscanf(argv[1], "%d", &num1) != 1) ||
(num1 < 2) ||
(num1 > 10000)) {
printf("You must give a number in range 2-10.000 as input\n");
return 0;
}
int x[num1], i;
for(i=0;i<num1;i++) {
x[i]=randu();
}
printf("Here are %d numbers\n", num1);
for (i=0;i<num1;i++) {
printf("%d\n",x[i]);
}
// Call the sort function
bubble(x, num1);
printf("Here are %d numbers sorted\n", num1);
for (i=0;i<num1;i++) {
printf("%d\n",x[i]);
}
return 0;
}
int randu(void) {
static int seed=17;
seed=(25179*seed+13849)%65536;
return seed;
}
void bubble(int a[], int num1){
int i,j;
for (i=0;i<num1-1;i++)
for(j=num1-1;i<j;j--)
if(a[j-1]>a[j])
swap(&a[j-1],&a[j]);
}
void swap(int *a, int *b){
int temp;
temp=*a;
*a=*b;
*b=temp;
}
"prog 5" gives the output:
Here are 5 numbers
48676
38117
52608
17049
29820
Here are 5 numbers sorted
17049
29820
38117
48676
52608

Resources