-2

WHAT THE PROGRAM DO:

I am making a program that displays how many times a number has been entered by the user. It will stop asking value if a number less than one has been entered.

SCREENSHOT AND EXAMPLE OF THE PROGRAM

I was able to create the program by initializing the value of the array "count" to 100. SCREENSHOT OF WHAT I DID.

The issue with this program, is that it will only accept values until 100. It will not accept values more than 100. This is a screenshot if more than a hundred value has been entered: SCREENSHOT OF MORE THAN 100

THE PROBLEM

This is where I want realloc() to come in. I want the to change the malloc() size depending on the highest entered value so it will be more flexible using realloc(). SCREENSHOT OF WHAT I CHANGED IN THE PROGRAM TO USE REALLOC()

However, doing so destroys the program. SCREENSHOT OF THE NEW OUTPUT OF THE PROGRAM

Please help me.

MY PROGRAM

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <stdbool.h>

main()
{
    //DECLARATION OF VARIABLES
    int i, j, k, highestValue=1, size=1;
    int* input = (int*)calloc(size, sizeof(int));
    int* count = (int*)calloc(highestValue, sizeof(int));

    bool iCondition = true;

    //USER INPUT
    for (i=0; iCondition==true; i++)
    {
        //GETS USER INPUT
        printf("Enter a number: ");
        scanf("%d", &input[i]);

        //CHECKS IF THE NUMBER ENTERED IS A HIGH NUMBER 
        if (highestValue<input[i]){
            highestValue = input[i];
            count = realloc(count, highestValue * sizeof(int));
        }


        //CHECKS HOW MANY TIMES THE NUMBER HAS BEEN ENTERED
        bool jCondition = true;
        for(j=0; jCondition==true; j++)
        {       
            if (input[i] == j){
                count[j-1]++;
                jCondition=false;
            }       
        }

        //ENDS THE LOOP IF THE ENTERED NUMBER IS LESS THAN 1
        if(input[i] < 1)
            iCondition = false;

        //IF NOT, THIS WILL REALLOCATE/CHANGE ARRAY SIZE BY ADDING +1!!
        else{
            size++;
            input = realloc(input, size * sizeof(int));
        }
    }

    //PRINTS OUTPUT | USES THE HIGHESTVALUE AS THE CONDITIONAL EXPRESSION FOR FLEXIBILITY
    for (i=0; i<=highestValue; i++)
    {   
        //PRINTS ALL NUMBER THAT IS NOT EQUAL TO ZERO(0)
        if (count[i] != 0)
            printf("\n %d was entered %d time/s ", i+1, count[i]);
    }   
    getch();
}
Karl John
  • 3
  • 4
  • 4
    Why do you post screenshots of text? Just post the text. – KamilCuk Nov 25 '19 at 12:26
  • I can see at least *one* place where specific input can lead to *undefined behavior*. You also have places where you use uninitialized and indeterminate values. – Some programmer dude Nov 25 '19 at 12:29
  • As for helping you solve your problems: Please learn how to use a *debugger* to step through your code statement by statement. Being able to use a debugger is a crucial skill if you're anywhere near serious about programming. – Some programmer dude Nov 25 '19 at 12:30
  • @KamilCuk Sorry, I'll be sure to do that next time! Thank you! – Karl John Nov 25 '19 at 12:32
  • @Someprogrammerdude ohhhh! Thank you for pointing that out! That is a very nice advice!! Thank you! – Karl John Nov 25 '19 at 12:34
  • Please humour me, and at least check the return values from calloc() and realloc() for NULL - which indicates an error. You are assuming it returns a valid pointer! – Andrew Nov 25 '19 at 13:21
  • 1
    You can use the `edit` button below your question to replace the links to pictures by the related text. – Gerhardh Nov 25 '19 at 13:59

1 Answers1

1

When you use realloc, the elements after the end of the old array are unitialized. Thus, your value can be anybody including garbage.

Before using the newly created elements you should initialize them using the standard means (using a loop, using memset)...

Edit: Since you only allocate one extra element with realloc, you can initialize it directly with input[size-1] = '\0'. Note that realloc has a non-trivial overhead so it is generally used to allocate multiple element at a time in real-life use cases.

Also, as mentionned by @KamikCuk, you should post directly text and not screenshots of text.

Maxime B.
  • 1,116
  • 8
  • 21
  • I'm not quite sure how bzero's work, but I'll be sure to try it out! Thank you! Moreover, I'm very sorry about the screenshots! I'm quite new here so I don't know how things work, so thank you for pointing that out! I'll be sure to directly put texts next time! – Karl John Nov 25 '19 at 12:38
  • HELLO! THANK YOU!! IT FINALLY WORKED!! Searching "bzero in C" through Google has made me encountered the memset()! memset() is basically bzero in C!! I have entered the following new line of code in my program! `memset(count, 0, highestValue*sizeof(count[0]));` – Karl John Nov 25 '19 at 12:50
  • @KarlJohn the `memset()` function is preferred over the `bzero()` function since `memset()` is part of the standard C library and `bzero()` is a Linux function which has been deprecated. See discussion in https://stackoverflow.com/questions/17096990/why-use-bzero-over-memset – Richard Chambers Nov 25 '19 at 12:50
  • Hello @RichardChambers! Thank you! I have used the memset() function and my program has successfully worked! Thank you so much for helping!! – Karl John Nov 25 '19 at 12:53
  • @RichardChambers That's right, `memset` is preferred over bzero. I edited it in the post. (I tend to say `bzero` since its totally self-explanatory like I would say `gets` even if it's very insecure thus I don't use it in practice. But I admit that it can be confusing for beginners so I edited this post with memset!) – Maxime B. Nov 25 '19 at 13:00
  • @KarlJohn If this answer solved your issue, you can [accept it](https://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work) – Maxime B. Nov 25 '19 at 13:07
  • @MaximeB. Thank you! Didn't know that there was an "Accept" button here! Thank you!! – Karl John Nov 25 '19 at 13:16