Can someone tell me why am i getting this error? - c

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)

Related

C programming call by reference pointer function to delete a member of a structure

This is for schoolwork and the question is asking to make a programme like a student database where I am able to input, print and remove students from the structure s using pointers function. However I am unable to delete the student records as something weird happens. The target student gets deleted but the rest of the students records(names only) are shifted, with only the first character being correct. Please help!
#include <stdio.h>
#include <string.h>
#define SIZE 50
typedef struct {
int id;
char name[50];
} Student;
void inputStud(Student *s, int size);
void printStud(Student *s, int size);
int removeStud(Student *s, int *size, char *target);
int main()
{
Student s[SIZE];
int size=0, choice;
char target[80], *p;
int result;
printf("Select one of the following options: \n");
printf("1: inputStud()\n");
printf("2: removeStud()\n");
printf("3: printStud()\n");
printf("4: exit()\n");
do {
printf("Enter your choice: \n");
scanf("%d", &choice);
switch (choice) {
case 1:
printf("Enter size: \n");
scanf("%d", &size);
printf("Enter %d students: \n", size);
inputStud(s, size);
break;
case 2:
printf("Enter name to be removed: \n");
scanf("\n");
fgets(target, 80, stdin);
if (p=strchr(target,'\n')) *p = '\0';
printf("removeStud(): ");
result = removeStud(s, &size, target);
if (result == 0)
printf("Successfully removed\n");
else if (result == 1)
printf("Array is empty\n");
else if (result == 2)
printf("The target does not exist\n");
else
printf("An error has occurred\n");
break;
case 3:
printStud(s, size);
break;
}
} while (choice < 4);
return 0;
}
void inputStud(Student *s, int size)
{
int i=0;
char *p,dummy[50];
while (i<size) {
printf("Student ID: \n");
scanf("%d",&((s+i)->id));
printf("Student Name: \n");
scanf("\n");
fgets((s+i)->name, 50,stdin);
if (p=strchr((s+i)->name,'\n')) *p = '\0';
i++;
}
}
void printStud(Student *s, int size)
{
int i;
printf("The current student list: \n");
if (size==0) printf("Empty array\n");
else {
for (i=0; i<size; i++) {
printf("Student ID: %d ",(s+i)->id);
printf("Student Name: %s\n",(s+i)->name);
}
}
}
int removeStud(Student *s, int *size, char *target)
{
int i,j,k;
if (*size==0) return 1;
for (i=0;i<*size;i++) {
if (strcmp(((s+i)->name),target)==0) {
--*size;
for (j=i; j<=*size; j++) {
k = j + 1;
*((s+j)->name) = *((s+k)->name);
(s+j)->id = (s+j+1)->id;
if ((s+j+1)->id=='\0') (s+j)->id = '\0';
}
return 0;
}
}
return 2;
}
you were almost there.
The problem is at line 97: *((s+j)->name) = *((s+k)->name);
To make it work, this instruction should be substituted with:
strcpy((s+j)->name, (s+k)->name);
Why:
you are coping with char arrays, so doing *((s+j)->name) = *((s+k)->name) means: "put the value of the first char of s+k->name into s+j->name first char".
Instead, you want to copy the whole name of s+k into the s+j name.
on how to use strcpy you can take a look here

Im trying to put return at the end of the code but they keep messing me up with while before return

Like i want to put the "return 0" at the right place, everything in the code is working normal.
complie the code and they keep saying about "while before return", i tried to put outside of the code and inside
#include <stdio.h>
#include <stdlib.h>
#define MAXN 100
int menu(){
printf("Menu:\n");
printf("1- Add a value\n");
printf("2- Search a value\n");
printf("3- Print out the array\n");
printf("4- Print out values in a range\n");
printf("5- Print out the array in ascending order\n");
printf("6- Quit?\n");
printf("Enter your operation: ");
int choice;
scanf("%d", &choice);
return choice;
}
int isFul (int*a, int n){
return n==MAXN;
}
int isEmpty (int*a, int n){
return n==0;
}
void add(int value, int*a, int*pn){
a[*pn] = value;
(*pn)++;
}
int search(int x, int *a, int n){
int i;
for (i=0; i<n; i++) if (a[i]==x) return i;
return -1;
}
void printvalueinrange (int*a, int n){
int i, min, max;
printf("\nEnter min value: ");scanf("%d", &min);
printf("\nEnter max value: ");scanf("%d", &max);
for(i=0; i<sizeof(a); i++)
if(a[i]>=min&&a[i]<=max) printf("%d", a[i]);
}
void printarray(int*a, int n){
int i;
for (i=0;i<n;i++) printf("%d", a[i]);
}
void printAsc(int*a, int n){
int** adds =(int**)calloc(n, sizeof(int*));
int i,j;
for(i=0; i<n; i++) adds[i]= &a[i];
int* t;
for (i=0;i<n-1; i++)
for(j=n-1; j>i; j--)
if (*adds[j]< *adds[j-i]){
t=adds[j];
adds[j]=adds[j-1];
adds[j-1]=t;
}
for (i=0;i<n; i++) printf("%d ", *adds[i]);
free(adds);
}
int main(){
int a[MAXN];
int n=0;
int value;
int choice;
do
{ choice= menu();
switch(choice){
case 1:{
if (isFull(a,n)) printf("\n Sorry! The array is full.\n");
else
{ printf ("Input an added value:");
scanf("%d", &value);
add(value, a, &n);
printf("Added!\n");
}
break;
}
case 2:{
if (isEmpty(a,n)) printf("\n Sorry! The array is empty.\n");
else
{ printf ("Input the searched value:");
scanf("%d", &value);
int pos = search(value, a, n);
if (pos<0) printf("Not found!\n");
else printf("Postion is found: %d\n", pos);
} break;
}
case 3:{
if (isEmpty(a,n)) printf("\n Sorry! The array is empty.\n");
else
{
printarray(a,n);
} break;
}
case 4:{
if (isEmpty(a,n)) printf("\n Sorry! The array is empty.\n");
else
{
printvalueinrange(a,n);
} break;
}
case 5:{
if (isEmpty(a,n)) printf("\n Sorry! The array is empty.\n");
else
{
printAsc(a,n);
} break;
}
default: printf ("Goodbye!");
break;
}
while (choice>0 && choice<7);
getchar();
}
return 0;
}
I just adding some word to fit with the requirement :"D
And if u find out any kind of error or mistake that in my code, just points out for me to improve them xd
In this part of main
}
while (choice>0 && choice<7);
getchar();
}
return 0;
}
the while construction occupies a wrong place.
There should be
}
} while (choice>0 && choice<7);
getchar();
return 0;
}
Also in this statement
if (isFull(a,n)) printf("\n Sorry! The array is full.\n");
^^^^^^
there is a typo. There should be
if (isFul(a,n)) printf("\n Sorry! The array is full.\n");

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().

How to use pointers to allocate an array inside another function

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);

Copying elements of array to a new one - C

I'm currently doing a school assignment and now I'm really stuck. The problem I have is that When I'm trying to copy the elements of the array dice to the array diceCheck the program goes in to some kind of infinite loop and I don't understand why. Help would be greatly appreciated!
Edit: It's in the bottom in the function printScores.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void printMenu(void);
void throwDice(int dice[], int nrOfDice, int nrOfDieValues);
void readDieValues (int dice[], int nrOfDice);
void printDice(const int dice[], int nrOfDice);
void printScores(const int dice[], int nrOfdice, int nrOfDieValues);
int isThreeOfAKind(const int dieValues[], int nrOfDieValues);
int isSmallStraight(const int dieValues[], int nrOfDieValues);
int main(void)
{
const int nrOfDice = 5;
const int nrOfDieValues = 6;
int dice[4], menuChoice = 0;
printMenu();
printf("\nMake your choice: ");
while(scanf("%d", &menuChoice) != -1)
{
switch (menuChoice)
{
case 0:
printMenu();
break;
case 1:
throwDice(dice, nrOfDice, nrOfDieValues);
printf("Make your choice: ");
break;
case 2:
readDieValues(dice, nrOfDice);
printf("Make your choice: ");
break;
case 3:
printDice(dice, nrOfDice);
printf("Make your choice: ");
break;
case 4:
printScores(dice, nrOfDice, nrOfDieValues);
break;
case -1:
return 0;
break;
default:
printf("Invalid choice!\n");
break;
}
}
return 0;
}
void printMenu()
{
printf("MENU:\n");
printf("0. Display the menu\n");
printf("1. Make a random throw\n");
printf("2. Enter die values for a throw\n");
printf("3. Display the die values for the throw\n");
printf("4. Display the score for the throw\n");
printf("-1. End program\n");
}
void throwDice(int dice[], int nrOfDice, int nrOfDieValues)
{
int choice, i;
printf("Enter seed (1 gives a random seed): ");
scanf("%d", &choice);
if(choice == 1)
{
srand(time(NULL));
for (i = 0; i < nrOfDice; i++)
{
dice[i] = ( rand() % nrOfDieValues) + 1;
}
printf("\n");
}
else
{
srand(choice);
for(i = 0; i < nrOfDice; i++)
{
dice[i] = ( rand() % nrOfDieValues) + 1;
}
printf("\n");
}
}
void readDieValues(int dice[], int nrOfDice)
{
int i;
for(i = 0; i < nrOfDice; i++)
{
printf("Die %d: ", (i+1));
scanf("%d", &dice[i]);
}
}
void printDice(const int dice[], int nrOfDice)
{
int i;
printf("Your dice: ");
for(i = 0; i < nrOfDice; i++)
{
printf("%d ", dice[i]);
}
printf("\n\n");
}
int isThreeOfAKind(const int dieValues[], int nrOfDieValues)
{
}
int isSmallStraight(const int dieValues[], int nrOfDieValues)
{
}
void printScores(const int dice[], int nrOfdice, int nrOfDieValues)
{
int diceCheck[4], i;
for(i = 0; i < nrOfdice; i++)
{
diceCheck[i] = dice[i];
printf("%d ", dice[i]); //these are just for myself to check if it worked
printf("%d ", diceCheck[i]); //these are just for myself to check if it worked
}
}
You have:
const int nrOfDice = 5;
but
int dice[4];
int diceCheck[4];
Your copying idea is correct but you are going one past the end of the array.
To avoid this sort of error, initialize both from the same expression, e.g.:
int dice[4];
const int nrOfDice = sizeof dice / sizeof dice[0];
or
const int nrOfDice = 4;
int dice[nrOfDice];
and inside the PrintScores function, instead of int diceCheck[4];, do:
int diceCheck[nrOfDice];

Resources