How to correctly use malloc in C? - c

I'm trying to allocate some memory using malloc in my program (I don't have much experience with malloc as I am just starting to learn how to use it). The program I've created works but I don't think I've used malloc correctly and I want to learn how to use it correctly.
The basic idea of my program is it takes 3 lines of input. The first line being whether you want to sort it by odd or even, the second line being how large your array is and the third line being the integers in the array.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char* sort;
int n;
int* ar;
int i;
void test()
{
int temp;
int j = 1;
if (strcmp(sort, "odd") == 0) {
for (i = 0; i < n;) {
if (j != n) {
if (ar[i] % 2 != 0) {
if (ar[j] % 2 != 0) {
if (ar[j] < ar[i]) {
temp = ar[i];
ar[i] = ar[j];
ar[j] = temp;
j++;
}
else {
j++;
}
}
else {
j++;
}
}
else {
j++;
i++;
}
}
else {
i++;
j = i + 1;
}
}
}
if (strcmp(sort, "even") == 0) {
for (i = 0; i < n; i++) {
if (j != n) {
if (ar[i] % 2 == 0) {
if (ar[j] % 2 == 0) {
if (ar[j] < ar[i]) {
temp = ar[i];
ar[i] = ar[j];
ar[j] = temp;
j++;
}
else {
j++;
}
}
else {
j++;
}
}
else {
j++;
i++;
}
}
else {
i++;
j = i + 1;
}
}
}
}
void main()
{
ar = malloc(sizeof(int) * 10);
sort = malloc(sizeof(char) + 5);
printf("Enter odd or even\n");
scanf("%s", sort);
printf("Enter the size of the array \n");
scanf("%d", &n);
printf("Enter the elements of the array \n");
for (i = 0; i < n; i++) {
scanf("%d", &ar[i]);
}
test();
for (i = 0; i < n; i++) {
printf("%d ", ar[i]);
}
}

You need to wait until they tell you the size of the array, and then use malloc() to allocate an array that size.
You don't need to use malloc for sort, you can just declare that as an ordinary array. In general, you use malloc() either when you need to allocate a dynamic number of items, or when the size of the item is dynamic, you don't need it for a single item with a fixed size.
int *ar;
char sort[5];
void main()
{
printf("Enter odd or even\n");
scanf("%s", sort);
printf("Enter the size of the array \n");
scanf("%d", &n);
ar = malloc(n * sizeof(int));
printf("Enter the elements of the array \n");
for (i = 0; i < n; i++) {
scanf("%d", &ar[i]);
}
test();
for (i = 0; i < n; i++) {
printf("%d ", ar[i]);
}
}

Related

I need help for bubble sort in c

How can I display the input user of this code. I am using bubble sort but I cannot display the input.
Here's my code:
#include <stdio.h>
int main(void) {
int array[100];
int count;
for(int i = 0; i < 100; i++) {
printf("Enter number %d: ", i + 1);
scanf("%d", &array[i]);
if(array[i] == 0) break;
}
int size = sizeof(array) / sizeof(array[0]);
for(int i = 0; i < size - 1; ++i) {
int swapped = 0;
for(int ctr = 0; ctr < size - i - 1; ++ctr) {
if(array[ctr] > array[ctr + 1]) {
int temp = array[ctr];
array[ctr] = array[ctr + 1];
array[ctr + 1] = temp;
swapped = 1;
}
}
if(swapped == 0) {
break;
}
}
printf("[");
for(int i = 0; i < size; i++) {
if(i == size - 1) {
printf("%d", array[i]);
}
else {
printf("%d, ", array[i]);
}
}
printf("]");
return 0;
}
Here's the output:
Enter·number·1:·1
Enter·number·2:·2
Enter·number·3:·3
Enter·number·4:·4
Enter·number·5:·5
Enter·number·6:·0
[1,·2,·3,·4,·5]
I cannot display the 1 2 3 4 5.... How can I display?
The calculation of the size doesn't work like you did it. sizeof(array) will give you the total amount of of bytes of the array (of all 100 spaces). So your size will allway be 100.
Instead of calculating the size it's easyer to count the inputs like this:
int size=0;
for(int i = 0; i < 100; i++) {
printf("Enter number %d: ", i + 1);
scanf("%d", &array[i]);
if(array[i] == 0) break;
size++;
}
The user can enter i values in the array due to the break statement within the for loop
for(int i = 0; i < 100; i++) {
printf("Enter number %d: ", i + 1);
scanf("%d", &array[i]);
if(array[i] == 0) break;
}
So you need to keep this value and use it the following for loops because it can differ from the value of the expression sizeof(array) / sizeof(array[0])

Print elements of an array that appear only once (C)

I am having trouble achieving the wanted results. The program should ask for 20 inputs and then go over each to see if they appear more than once. Then only print out those that appeared once.
However currently my program prints out random numbers that are not inputted.
For example:
array = {10,10,11,12,10,10,10.....,10} should return 11 and 12
#include <stdio.h>
void main() {
int count, size=20, array[size], newArr[size];
int number=0;
for(count = 0; count < size; count++) {
// Ask user for input until 20 correct inputs.
printf("\nAnna %d. luku > ", count+1);
scanf("%d", &number);
if( (number > 100) || (number < 10) ) {
while(1) {
number = 0;
printf("Ei kelpaa.\n");//"Is not valid"
printf("Yrita uudelleen > ");//"Try again >"
scanf("%d", &number);
if ( (number <= 100) && (number >= 10) ) {
break;
}
}
}
array[count] = number;
}
for(int i=0; i < size; i++) {
for(int j=0; j<size; j++){
if(array[i] == array[j]){
size--;
break;
} else {
// if not duplicate add to the new array
newArr[i] == array[j];
}
}
}
// print out all the elements of the new array
for(int k=0; k<size; k++) {
printf("%d\n", newArr[k]);
}
}
You don't need the newArr here, or the separate output loop. Only keep a count that you reset to zero at the beginning of the outer loop, and increase in the inner loop if you find a duplicate.
Once the inner loop is finished, and the counter is 1 then you don't have any duplicates and you print the value.
In code perhaps something like:
for (unsigned i = 0; i < size; ++i)
{
unsigned counter = 0;
for (unsigned j = 0; j < size; ++j)
{
if (array[i] == array[j])
{
++counter;
}
}
if (counter == 1)
{
printf("%d\n", array[i]);
}
}
Note that the above is a pretty naive and brute-force way to deal with it, and that it will not perform very well for larger array sizes.
Then one could implement a hash-table, where the value is the key, and the count is the data.
Each time you read a value you increase the data for that value.
Once done iterate over the map and print all values whose data (counter) is 1.
Use functions!!
Use proper types for indexes (size_t).
void printdistinct(const int *arr, size_t size)
{
int dist;
for(size_t s = 0; s < size; s++)
{
int val = arr[s];
dist = 1;
for(size_t n = 0; n < size; n++)
{
if(s != n)
if(val == arr[n]) {dist = 0; break;}
}
if(dist) printf("%d ", val);
}
printf("\n");
}
int main(void)
{
int test[] = {10,10,11,12,10,10,10,10};
printdistinct(test, sizeof(test)/sizeof(test[0]));
fflush(stdout);
}
https://godbolt.org/z/5bKfdn9Wv
This is how I did it and it should work for your:
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <stdarg.h>
void printdistinct(const int *muis, size_t size);
int main()
{
int loop=20,i,muis[20],monesko=0;
for(i=0; i<loop; i++){
monesko++;
printf ("Anna %d. luku: \n",monesko);
scanf("%d", &muis[i]);
if (muis[i]<10 || muis[i]>100){
printf("Ei kelpaa!\n");
muis[i] = muis[i + 1];
printf("YRITÄ UUDELLEEN:\n ");
scanf("%d", &muis[i]);
}
}
printdistinct(muis, sizeof(muis)/sizeof(muis[0]));
fflush(stdout);
return 0;
}
void printdistinct(const int *muis, size_t size)
{
for(size_t s = 0; s < size; s++)
{
int a = muis[s];
int testi = 1;
for(size_t n = 0; n < size; n++){
if(s != n) {
if(a == muis[n]){
testi = 0;
break;
}
}
}
if(testi) {
printf("%d \n", a);
}
testi = 1;
}
printf("\n");
}
This approach uses some memory to keep track of which elements are duplicates. The memory cost is higher, but the processor time cost is lower. These differences will become significant at higher values of size.
char* duplicate = calloc(size, 1); // values are initialized to zero
for (unsigned i = 0; i < size; ++i)
{
if(!duplicate[i]) // skip any value that's known to be a duplicate
{
for (unsigned j = i + 1; j < size; ++j) // only look at following values
{
if (array[i] == array[j])
{
duplicate[i] = 1;
duplicate[j] = 1; // all duplicates will be marked
}
}
if (!duplicate[i])
{
printf("%d\n", array[i]);
}
}
}
What you can do is you can initialize a hashmap that will help you store the unique elements. Once you start iterating the array you check for that element in the hashmap. If it is not present in the hashmap add it to the hashmap. If it is already present keep iterating.
This way you would not have to iterate the loop twice. Your time complexity of the algorithm will be O(n).
unordered_map < int, int > map;
for (int i = 0; i < size; i++) {
// Check if present in the hashmap
if (map.find(arr[i]) == map.end()) {
// Insert the element in the hash map
map[arr[i]] = arr[i];
cout << arr[i] << " ";
}
}

arrange the array in an order such that the even values are followed by odd values in the array

this is the program I made ,if I input [13,11,10,17,18] i get the output [12,13,17,11,10]. I do not understand what mistake I am making. somebody please help me understand.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int* ptr;
int n,j,i,num,v;
printf("Enter number of elements:");
scanf("%d",&n);
printf("Entered number of elements: %d\n", n);
ptr = (int*)malloc(n * sizeof(int));
for (i = 0; i < n; ++i) {
scanf("%d",&v);
ptr[i] = v;
}
i=0;
j=0;
while(i<5){
j++;
if (ptr[j]%2==0 && i%2==0){
num=ptr[i];
ptr[i]=ptr[j];
ptr[j]=num;
}
if (ptr[j]%2!=0 && i%2 !=0){
num=ptr[i];
ptr[i]=ptr[j];
ptr[j]=num;
}
if (j==4){
i++;
j=0;
}
}
printf("The elements of the array are: ");
for (i = 0; i < n; ++i) {
printf("%d, ", ptr[i]);
}
}
Ok, I tried to tell you how you should have written you program, but you didn't listen:
Make a https://stackoverflow.com/help/minimal-reproducible-example
A MCVE needs all the includes
No interactive stuff. You need to run and run and run your program in a debugger. You don't want to put data in manually every single time.
You want many tests, and you want to repeat them, so that when you fix one, you don't break another.
Make a function which does the job.
Free your memory!
Now to the solution: your idea of a solution was fine apart from the stuff about indexes. It's pretty similar to the one you will find down here. The only difference is that I put the odd numbers al the end to avoid checking elements multiple times.
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
void evenodd(int *v, size_t n)
{
for (size_t i = 0; i < n; ++i) {
while (i < n && v[i] % 2 == 0) {
++i;
}
--n;
while (i < n && v[n] % 2) {
--n;
}
if (i < n) {
int tmp = v[i];
v[i] = v[n];
v[n] = tmp;
}
}
}
bool is_evenodd(int *v, size_t n)
{
size_t i = 0;
while (i < n && v[i] % 2 == 0) {
++i;
}
while (i < n && v[i] % 2 != 0) {
++i;
}
return i == n;
}
void main_test(const int *v, size_t n)
{
int *v1 = memcpy(malloc(n * sizeof(int)), v, n * sizeof(int));
evenodd(v1, n);
if (is_evenodd(v1, n)) {
printf("Ok!\n");
}
else {
printf("Fail!\n");
}
free(v1);
}
int main(void)
{
main_test((int[]) { 1 }, 0);
main_test((int[]) { 1 }, 1);
main_test((int[]) { 2 }, 1);
main_test((int[]) { 1, 2 }, 2);
main_test((int[]) { 1, 3 }, 2);
main_test((int[]) { 2, 1 }, 2);
main_test((int[]) { 2, 4 }, 2);
main_test((int[]) { 1, 3, 2 }, 3);
main_test((int[]) { 1, 4, 2 }, 3);
size_t n = 1000;
int *a = malloc(n * sizeof *a);
for (size_t i = 0; i < n; ++i) {
a[i] = rand();
}
main_test(a, n);
free(a);
return 0;
}
You can try the following code :
int even_index = 0; //start index
int odd_index = 4; //end index
for(int i=0;i<5;i++){
if(ptr[i] % 2 == 0){
int temp = ptr[even_index];
ptr[even_index++] = ptr[i]; //swapping values and incrementing even_index
ptr[i] = temp;
}else{
int temp = ptr[odd_index];
ptr[odd_index--] = ptr[i];
ptr[i] = temp;
}
}
or you can also count the number of even numbers in the digits during input and assign odd_value = even_num // number of even digits
ok so I solved it....
see the even numbers always end up in even indexes so we need to set a pointer on those even index(current index) and search for any even number after the current index.
if we find any(even number) we swap the current index value with the even number.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int* ptr;
int n,j,i,num,v;
printf("Enter number of elements:");
scanf("%d",&n);
printf("Entered number of elements: %d\n", n);
ptr = (int*)malloc(n * sizeof(int));
for (i = 0; i < n; ++i) {
scanf("%d", &v);
ptr[i] = v;
}
i=0;
j=0;
while(i<n && j<n){
if (ptr[j]%2==0){
num=ptr[i];
ptr[i]=ptr[j];
ptr[j]=num;
i+=2;
j=i;
}
j++;
}
printf("The elements of the array are: ");
for (i = 0; i < n; ++i) {
printf("%d, ", ptr[i]);
}
}
If this problem is to sort an array in order (descending) and then further place all even values before odd values I would recommend:
Sort the array
Swap and shift any odd numbers with the even numbers
Here's a naive implementation:
for (int i = 0; i < len - 1; i++) {
for (int j = i + 1; j < len; j++) {
if (arr[i] < arr[j]) {
tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
}
int lastEven = 0;
for (int i = 0; i < len - 1; i++) {
if (arr[i] % 2 && (arr[i + 1] % 2 == 0)) {
tmp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = tmp;
lastEven = i;
} else if (arr[i] % 2 == 0 && lastEven-i > 1) {
for (int j = i; j > lastEven; j--) {
tmp = arr[j-1];
arr[j-1] = arr[j];
arr[j] = tmp;
}
lastEven++;
}
}
Given the input [13,11,10,17,18] this will first sort the array ([18,17,13,11,10]) then separate the evens and odds ([18,10,17,13,11])

I am trying to find the duplicate of elements in an array

Can someone help me to figure out why my code is unable to accurately find the duplicate of elements?
#include <stdio.h>
int main() {
int array[10];
int count = 0;
printf("Enter a maximum of 10 values to store in an array: ");
for (int i = 0; i < 10; i++) {
scanf_s("%d", &array[i]);
}
for (int i = 0; i < 10; i++) {
for (int j = i + 1; j < 10; j++) {
if (array[i] == array[j]) {
count++;
break;
}
}
}
printf("The duplicates are : %d ", count);
}
I'm a beginner at this language so any advice and suggestions to help me solve this exercise will be much appreciated.
First of all the first loop runs 10 times even if the user enters less numbers. You can fix that by doing:
for (int i = 0; scanf_s("%d", &array[i]) == 1 && i < 10; i++);
Then the logic of the other two loops is wrong. I initially got wrong what you meant. I thought you wanted to know how many times a number is duplicated. So I wrote the wrong program and then modified it for your purposes. Here is your program:
#include <stdio.h>
int main() {
int n[10];
int dupes[5], d = 0;
int flag = 1, omg;
for ( omg = 0; scanf("%d", &n[omg]) == 1 && omg < 10; omg++);
for (int i = 0; i < omg; i++) {
for (int j = i+1; j < 10; j++) {
if( n[i] == n[j] ) {
if( d > 0 ) {
for(int k = 0; k < d; k++) {
if( n[i] == dupes[k] ) {
flag = 0;
break;
}
}
}
if( flag ) {
dupes[d] = n[i];
++d;
break;
}
else {
flag = 1;
break;
}
} // end outer if
}
}
printf("There are %d numbers that have at least one dupe\n", d);
return 0;
}
I named a variable omg out of desperation, writing this program was a nightmare. (Because it came from the ashes of a previous program)
Your code correctly determines the number of duplicate entries in the array.
If instead you want to determine the number of duplicated values, you must modify the algorithm:
#include <stdio.h>
int main() {
int array[10] = { 0 };
int count = 0;
printf("Enter a maximum of 10 values to store in an array: ");
for (int i = 0; i < 10; i++) {
scanf_s("%d", &array[i]);
}
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
if (array[i] == array[j]) {
if (i < j)
count++;
if (i != j)
break;
}
}
}
printf("There are %d duplicate values\n", count);
return 0;
}
I use a structure 'Number' which contains the number and its duplicate, then I fill the array and I put it in ascending order then I calculate the number of duplicate of each number and I fill in the strecture like this :
my code:
#include <stdio.h>
#define size 10
typedef struct Number
{
int number;
int duplicate;
}Number;
int main()
{
int array[size];
Number array2[size];
int count = 0;
printf("Enter a maximum of 10 values to store in an array: ");
for (int i = 0; i < size; i++)
{
scanf("%d", &array[i]);
}
int temp=size;
int temppppp=0;
for(int i=0;i<size;i++)
{
for(int j=i+1;j<size;j++)
{
if(array[i]>array[j])
{
temppppp=array[i];
array[i]=array[j];
array[j]=temppppp;
}
}
}
printf("\n\n");
for (int i = 0; i < size; i++)
{
printf("[%d]",array[i]);
}
printf("\n\n");
int i=0;
int j=0;
while(i<size)
{count=1;
while(i<(size-1)&&array[i]==array[i+1])
{
count++;
i++;
}
if(count>=2)
{
array2[j].number=array[i-1];
array2[j].duplicate=count;
j++;
}
i++;
}
int p=0;
while(p<j)
{
printf("\n[%d] has duplicated %d times !\n",array2[p].number,array2[p].duplicate);
p=p+1;
}
printf("\n\n");
printf("\nThere are %d duplicate values\n", j);
}

How to print all elements of an array in C after I enter all of them?

So I have this code in C:
#include <stdio.h>
int main() {
int a[9], number_of_elements;
printf("Enter 10 numbers: \n");
for (int i = 0; ((i < 10) && (a[i] != 0)); i++) {
scanf_s("%d", &a[i]);
if (a[i] == 0) {
number_of_elements = i;
break;
}
if (a[i] != 0) {
number_of_elements = i + 1;
}
}
printf("There is %d elements.\n", number_of_elements);
return 0;
}
As you can see, I have to enter max 10 elements into an array, or stop entering when you enter 0, and after that I have to print all elements of that array and how many elements array have. I sorted all things except printing all elements of the array, can anyone help me how to do that?
You should use another for loop, like:
for(i=0;i<number_of_elements;i++)
{
printf("%d ",a[i]);
}
After implementing #rsp's code, I fixed my code.
#include <stdio.h>
int main() {
int a[10], number_of_elements;
printf("Enter 10 numbers: \n");
for (int i = 0; ((i < 10) && (a[i] != 0)); i++) {
scanf_s("%d", &a[i]);
if (a[i] == 0) {
number_of_elements = i;
break;
}
if (a[i] != 0) {
number_of_elements = i + 1;
}
}
for (int i = 0; i<number_of_elements; i++)
{
printf("%d ", a[i]);
}
printf("\nThere are %d elements.\n", number_of_elements);
return 0;
}
Tnx everyone for help and tnx #George for being so funny :)

Resources