-2

So I am trying to make a program that stores user input into a dynamic array but I cant do it right. When I try to put a number let us say 1, and I want to try again then I want to view history, the only thing that shows up is the last number I have input. And sometimes there is a large number sowing up like 1214098101909279242 like that.

Here is my code:

#include<iostream>
    using namespace std;
    int main(){
        const int size = 20;
        int *num = new int[size];
        char answer;
        while(true){
        cout<<"ENTER NUMBER: \n";
        cin>>*num;
        cout<<"TRY AGAIN? ";
        cin>>answer;
            switch(answer){
                case 'y':
                    num[size+1];
                    system("cls");
                    break;
                default:
                    cout<<"INPUT HISTORY: \n";
                    for(int i=0;i<=size;i++){
                        cout<<num[i];
                    }
            }
        }
        return 0;
    }
newbie
  • 33
  • 1
  • 6
  • 4
    Please include compiler errors in the question and/or explain what is wrong with the code – 463035818_is_not_an_ai Mar 05 '20 at 12:36
  • 1
    Hello, that's some funky indentation you got there. Care to fix it? – YSC Mar 05 '20 at 12:36
  • 1
    " I cant do it right" is not a proper description of your issue. Actually your entire post is hardly a little more than "here is my code. Fix it for me". Please post the expected behavior, the observed behavior along with the errors your get (if any) – bolov Mar 05 '20 at 12:38
  • 1
    arrays have fixed size, use `std::vector` when you want something resizable – 463035818_is_not_an_ai Mar 05 '20 at 12:38
  • 1
    Hints: `int number_of_stored_inputs = 0;`. `num[number_of_stored_inputs]`. `*num` is the same as `num[0]`. `num[size+1];` doesn't do anything. – user253751 Mar 05 '20 at 12:45
  • @user253751 so *(num+1) is the same as num[1] ? – newbie Mar 05 '20 at 12:53
  • 1
    @newbie yes it is – user253751 Mar 05 '20 at 12:57
  • @user253751 one more question. In my code I used int *num = new int[size], I wanna ask what really is the use of new int [size]. Does it make the *num an array? – newbie Mar 05 '20 at 13:04
  • 1
    I suggest that if you want to know what `new int[size]` does you can ask that separately. It will probably be closed as a duplicate, because someone has already asked that. Or you can find where someone has asked that and answered it. – user253751 Mar 05 '20 at 13:09

2 Answers2

1

I have two major issues with your code:

  1. There is no need for dynamic allocation in this case, since size is a const value (and can be defined as constexpr, which is better).
  2. instead of using the standard containers (such as std::array (for constant size array) or std::vector (for dynamically expanding array)) you use a plain pointer array, which is ill-advised, and in this case can cause memory leak (for example, if you move this code into an utility function, since you never delete the memory of num array!), you should use std::unique_ptr instead! (and better read about the RAII idiom).
  3. Spacing and indentation - your code should be readable to other coders as well.

About your code, the original code have the following line:

cin >> *num

which means put the value in stdin into the FIRST position of num. In both C/C++, arrays are just pointers to the first address of memory that was allocated for the array. In order to access the other items, you need to use the operator[] or use pointer arithmetic with the operator* (for example:

cin >> *(num + count)

will get the item at position count). Also, as pointed above, there is no safety measure for disallowing writing to an invalid memory that you can count on. Therefore, you should use the std containers which enforce index safety.

Just for reference, here is the code I would have wrote to get the same functionality:

int main() {
    constexpr size_t SIZE = 20;
    std::array<int, SIZE> arr;
    arr.fill(0);

    int last_filled_position = 0;
    bool cont = true;

    while (cont)
    {
        int val;
        char answer;

        cout << "ENTER NUMBER:" << std::endl;

        cin >> val;

        cout<<"TRY AGAIN? Yes/Print/Stop";

        cin >> answer;

        arr.at(last_filled_position++) = val;

        switch (answer)
        {
            case 'y':
                system("cls");
                break;
            case 'p':
                cout << "INPUT HISTORY: " << std::endl;

                for (int val: arr) // With more complex types, you should use const auto&
                {
                    cout << val << ", ";
                }

                cout << endl;
                break;
            case 's':
                cont = false;
                cout << "STOPPING";
                break;
        }
    }

    return 0;
}
Kerek
  • 1,106
  • 1
  • 8
  • 18
  • thanks for helping but when i tried it in my c++ compiler there is an error that is showing [Error] 'constexpr' was not declared in this scope, [Error] 'array' is not a member of 'std', [Error] expected primary-expression before 'int', [Error] 'arr' was not declared in this scope, [Error] range-based 'for' loops are not allowed in C++98 mode thats what it says. – newbie Mar 05 '20 at 14:03
  • 1
    @newbie what compiler and version are you using? – JohnFilleau Mar 05 '20 at 14:23
  • This is a newer standard - you should use C++11 and higher. Many of the basic "problems" of C++ were fixed at that update. Assuming you are using g++, run the following: g++ --std=c++11 code.cpp – Kerek Mar 05 '20 at 14:23
  • @John Dev C++ 5.11 – newbie Mar 05 '20 at 14:36
  • 1
    @newbie I recommend visual studio 2019 if you're on windows. If you're stuck with Dev C++, you can apparently update command line options to the compiler using [this](https://stackoverflow.com/questions/16951376/how-to-change-mode-from-c98-mode-in-dev-c-to-a-mode-that-supports-c0x-ran) method to compile in at least c++11 mode – JohnFilleau Mar 05 '20 at 14:38
  • @newbie you are talking about IDE and not the compiler. According to google, it uses the g++ compiler, you should use the following answer to set it to std c++11: https://stackoverflow.com/a/16951613/7014837 – Kerek Mar 05 '20 at 14:39
  • 1
    This is 2020. There's no reason you should be stuck coding in C++98, just like we shouldn't be building our own computers using vacuum tubes and we shouldn't be programming using punch cards, except as a weird hobby that our significant others silently judge us for. – JohnFilleau Mar 05 '20 at 14:40
  • @newbie as John said, this is not a very common IDE, you should use Visual Studio or Visual Studio Code (open source, lighter) instead of Dev C++. – Kerek Mar 05 '20 at 14:41
  • @newbie Anyhow, the answer itself explains the behavior you found strange. If you find the answer helpful, you should accept it as correct. – Kerek Mar 05 '20 at 14:44
  • OK thanks for the advice, so I should use Visual Studio from now on? – newbie Mar 05 '20 at 14:45
  • 1
    @newbie when selecting any piece of hardware or software, picking one that has more support, more recent updates, and is used by more people can help you answer questions about it faster when you need help. I used to own a 98 Saab, but I needed transmission work done on it and no garage in town wanted to touch it because they didn't have experience on it. I finally got rid of the thing and got a Honda. Every garage knows how to work on a Honda. Use Visual Studio. – JohnFilleau Mar 05 '20 at 14:51
0

So I have change the code a little bit. Is my code valid for some reason? because it works fine now. I can input numbers and when i view all the numbers, it works fine.

#include<iostream>
using namespace std;
int main(){
    const int size = 20;
    int *num = new int[size];
    char answer;
    int count = 1;
    while(true){
    cout<<"ENTER NUMBER: \n";
    cin>>num[count-1];
    cout<<"TRY AGAIN? ";
    cin>>answer;
        switch(answer){
            case 'y':
                count++;
                system("cls");
                break;
            default:

                cout<<"INPUT HISTORY: \n";
                for(int i=0;i<=count-1;i++){
                    cout<<num[i]<<endl;
                }
                count++;
        }
    }
    return 0;
}
newbie
  • 33
  • 1
  • 6
  • 1
    Yes, I think this works. You should be able to figure out the reason yourself. – user253751 Mar 05 '20 at 12:57
  • @user253751 is there a misuse in code? because someone told me that there are "VLA;s" that don't accept something. – newbie Mar 05 '20 at 13:00
  • 1
    I don't see any mistakes. C++ doesn't have VLAs. C has VLAs, which are just arrays, where you don't have to use `new` even though the compiler doesn't know the size. – user253751 Mar 05 '20 at 13:01
  • 1
    If you try a lot of times (more than 20), you might overwrite something important in memory and the program might crash. I do not count this as a mistake, because I think you know about that problem already, and maybe you haven't learned how to solve it yet. – user253751 Mar 05 '20 at 13:03
  • 2
    Your program is far from being fine and error free. There is no reason to use a dynamic array here because you never change it's size. You dont check the number of inputs so entering more than 20 numbers results in undefined behaviour. And your code has a memory leak because you never delete your dynamically allocated array. What you need is a good c++ book that explains the basics of the language. – Eric Mar 05 '20 at 13:07
  • @user253751 so maybe i should increment the size every time the user wants to try again so that it would not overwrite? – newbie Mar 05 '20 at 13:07
  • @newbie the way to increase a dynamic array in C++ is to request a `new int[]` of the desired size, copy the contents of the old array into the new array, and then `delete[]` the old array. If you don't `delete[]`, then your program will keep requesting more and more memory from the OS without giving the old memory back. A better solution is to use `std::vector`, which resizes automatically when you want to insert more elements. – JohnFilleau Mar 05 '20 at 14:28
  • @John so how can I manually delete the old memory from my OS. I know this is off topic but I am worried that my laptop memory will be reduced. – newbie Mar 05 '20 at 14:43
  • @newbie - your memory won't permanently be reduced. Most modern operating systems are very good about reclaiming resources from terminated processes. But during the runtime of your program, the memory footprint will grow if you don't `delete` any memory acquired with `new`. Using `new` asks the OS for a block of memory. Using `delete` says to the OS, "thanks for that memory, I'm done with it, you may have it back", and the OS knows it can use it for other applications now. If you keep `new`ing without complementary `delete`ing, you'll never give the OS back the memory (until a program crash) – JohnFilleau Mar 05 '20 at 14:45
  • @newbie with that in mind, we call the explicit use of `new` and `delete` in our programs "manual memory management", because we as programmers need to remember to `delete` everything we `new`. There's a concept called [RAII](https://en.cppreference.com/w/cpp/language/raii) where an OBJECT is responsible for memory management (or management of some other resource like a web socket or an IO pin or something). We just create the object, the object is responsible for managing memory, and when the object is destroyed (at the end of a function for example) it cleans everything up. So use `vector` – JohnFilleau Mar 05 '20 at 14:48
  • @John oh thanks for that clear explanation. I now know the new and delete in c++. Also I want to ask what is the difference with and with 'new'; – newbie Mar 05 '20 at 14:54
  • @newbie you might need to edit your comment there I can't understand what you're asking. Are you learning C++ in an academic setting or from some other resource? We have a [book list](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) if you need a good book. – JohnFilleau Mar 05 '20 at 14:55
  • @John Yes I am learning C++ in an academic setting. What I meant to ask is what does 'new' really do? – newbie Mar 05 '20 at 15:01
  • @John does 'new' do what arrays do? Because you said that it asks for a block of memory. – newbie Mar 05 '20 at 15:02
  • @newbie if you just create a "local" array, that memory is "automatically" allocated. usually, the compiler achieves this by just telling the program to increase the stack by enough bytes the fit the darned thing upon entering the function in which you declare the array. When you leave scope (the function), though, the stack goes back to its old size and the memory that your array was sitting in can now be used by other functions. Attempting to access this is called "undefined behavior" – JohnFilleau Mar 05 '20 at 15:22
  • @newbie `new` is dynamic allocation [see here](https://en.cppreference.com/w/cpp/language/new). Dynamic memory is NOT invalidated when you leave scope (leave a function). You can still access it later on in the program. Dynamic memory is normally allocated from a heap, but not always the case. It depends on your compiler, operating system (if you even have an OS) etc. Since stack allocation needs to be known at compile time, local arrays need their size known at compile time. Many compilers DO support something called VLA - variable length arrays - but you should avoid them when possible. – JohnFilleau Mar 05 '20 at 15:24
  • If you need a block of contiguous memory that changes size and its size is unknown at compile time (i.e., you ask a user to tell you), use a `std::vector`. If you know that your array will always be a certain size, you can get away with a local array. – JohnFilleau Mar 05 '20 at 15:25