Search code examples
c++arrayspointersallocation

Logical Error at the Output


I'm working on a program which creates dynamic array using pointers and then reallocates it.

The problem is that the program runs successfully but gives the wrong output. Any help would be appreciated.

int main()
{
    int n;
    cout<<"Please enter the size of the array: ";
    cin>>n;

    int *arr1;
    arr1 = new int[n];
    int *arr1_1;

    arr1_1=arr1;

    cout<<"Enter "<<n<<" elements in the array \n";
    int x=0;

    while(x<n)
    {
        cin>>arr1[0];
        arr1++;
        x++;
    }

    x=0;
    arr1=arr1_1;

    cout<<"Here's what you've inserted in the array: \n";
    while(x<n)
    {
        cout<<arr1[0]<<endl;;
        arr1++;
        x++;
    }

    arr1=arr1_1;

    cout<<"\n\n";
    cout<<"Do you want to extend the size of the array? \nAnswer with 'Y' or 'N'. "<<endl;
    char ans;
    cin>>ans;

    int n1;
    if(ans=='Y' || ans=='y'){
        cout<<"According to you, What should be the new size of array? ";
        cin>>n1;
        cout<<"You can enter new elements in your existing array now.\n"; 
    }
    else{
        cout<<"Ok, then! Have a nice day.";
    }

    int *arr2, *arr2_1;

    arr2=(int *) realloc (arr1, n1*sizeof(int));

    arr2_1=arr2;
    x=0;

    while(x<n)
    {
        arr2[0]=arr1[0];
        arr1++;
        arr2++;
        x++;
    } 

    x=n;
    while(x<n1){
        cin>>arr2[n+1];
        arr2++;
        x++;
    }
    arr2=arr2_1;
    x=0;


    while(x<n1){
        cout<<arr2[0]<<endl;
        arr2++;
        x++;
    }

    return 0;
}

Solution

  • I have revised your code and commented it. I hope that it can help you:

    #include <iostream>
    
    using namespace std;
    
    int main()
    {
        //int n;//CALL YOUR VARIABLES WITH SUGGESTIVE NAMES
        int array_size;
    
        do
        {
            cout << "Please enter the size of the array: ";
            cin >> array_size;
        }
        while(array_size <= 0);//you don't want a pointer which points to 0 elements or less
    
    
        int* arr1 = nullptr;//INITIALIZE YOUR POINTERS TO NULL or nullptr (C++11)
        arr1 = new int[array_size];
        int* arr1_1 = nullptr;
    
        arr1_1 = arr1;
        //arr1_1 is pointing to the same memory location of arr1
        //So once you delete arr1 or arr1_1 pointer, you don't have anymore to free the same memory location
        //If you do it, you will probably have an error.
    
        cout << "\nEnter "<< array_size <<" elements in the array:\n";
    
        //int x=0;
        //WHY ARE YOU USING A WHILE LOOP? THIS IS REALLY THE CASE WHERE YOU SHOULD USE A FOR LOOP
        //CAUSE YOU KNOW EXACTLY THE NUMBER OF TIMES THE LOOP IS GOING TO ITERATE.
        //while(x<n)
        //{
        //cin>>arr1[0];//WHY arr1[0]? YOU ARE GOING TO PUT AND OVERRIDE ALL THE ELEMENTS IN THE FIRST POSITION
        //arr1++;
        //x++;
        //}
    
        for(int i=0; i<array_size; ++i)
        {
            cout << "Enter your "<< i + 1 << ". number: ";
            cin >> arr1[i];//YOU HAVE TO PUT THE ELEMENT AT THE 'i' POSITION
        }
    
        //x=0;//YOU DON'T NEED ANYMORE THIS VARIABLE BECAUSE YOU SHOULD USE A FOR LOOP
    
        arr1=arr1_1;//WHAT EXACTLY IS THIS? THEY ARE ALREADY POINTING TO THE SAME MEMORY LOCATION
        //SO THIS ASSIGNMENT IS SUPERFLOUS
    
        cout << "\nHere's what you have inserted in the array: \n";
    
        //STILL: USE A FOR LOOP ;)
        //while(x<n)
        //{
        //  cout<<arr1[0]<<endl;;
        // arr1++;
        //x++;
        //}
    
        for(int i=0; i<array_size; ++i)//JUST 1 STATEMENT, YOU DON'T NEED PARENTHESIS
            cout << "Element number "<< i + 1 << " is: "<< arr1_1[i] << '\n';
    
    
        //arr1=arr1_1;
    
        cout<<"\n\n";
        cout<<"Do you want to extend the size of the array? \nAnswer with 'Y' or 'N'. "<<endl;
        char ans;
        cin >> ans;
    
        //int n1;//SUGGESTIVE NAMES HELP YOU TO READ THE CODE WHEN YOU WILL NEED TO DO IT
        int new_size;
    
        bool isSizeChanged = false;
    
        if(ans=='Y' || ans=='y')
        {
            isSizeChanged = true;//YOU WILL SEE AT THE END, 
             //WHEN YOU WANT TO FREE THE POINTERS, THAT THIS VARIABLE IS USEFUL
    
            cout<<"According to you, what should be the new size of array? ";
            cin >> new_size;
    
            if(new_size > 0)//YOU DON'T WANT TO MAKE arr1_1 INITIALIZE WITH 0 ELEMENTS
            {
                cout<<"You can enter new elements in your existing array now.\n";
            //YOU SHOULD PUT HERE THE CODE WHICH REALLOCATES MEMORY
    
            //Both arr1 and arr1_1 are pointing to the same memory location, 
            //but you can make 1 of them to point to another location!
    
                arr1_1 = new int[new_size];
    
                //COPYING THE ELEMENTS FROM arr1 TO arr1_1, 
                //WHICH NOW IS POINTING TO A DIFFERENT MEMORY LOCATION
    
                if(new_size >= array_size)//NOTE THAT IF THIS CONDITION IS TRUE, YOU WILL HAVE SOME LOCATIONS POINTED WITH RANDOM VALUES!!!
                {
                    for(int i=0; i<array_size; ++i)
                        arr1_1[i] = arr1[i];
                }
                else//new_size is less than array_size
                {
                    for(int i=0; i<new_size; ++i)//NOTE THAT NOW I AM USING new_size
                        arr1_1[i] = arr1[i];
                }
    
                cout << "\nYour new array contains:\n";
    
                for(int i=0; i<new_size; ++i)
                    cout << "Element number "<< i +1 << ". is: "<<arr1_1[i] << '\n';
    
            }
            else
                cout << "Sorry, we cannot change the size of the pointer to 0 or less.\n";
        }
        else
            cout<<"Ok, then! Have a nice day.";
    
        //WHY ARE YOU DECLARING A NEW POINTERS?
        //YOU CAN USE 1 OF THE PREVIOUS POINTERS
        //int *arr2, *arr2_1;
    
        //YOU SHOULDN'T USE THE C STYLE TO REALLOCATE A POINTER, IT'S HARDER TO DO IT
        //arr2=(int *) realloc (arr1, n1*sizeof(int));
    
        //arr2_1=arr2;//OK, THIS WOULD HAVE WORKED :)
        //x=0;
    
        //I WOULD SUGGEST YOU TO USE A FOR LOOP ALSO IN THIS SITUATION
        //while(x<n)
        //{
        //arr2[0]=arr1[0];//YOU ARE COPYING THE FIRST ELEMENT OF arr1 TO THE FIRST ELEMENT OF arr2, ALWAYS!!
        //arr1++;
        //arr2++;
        //x++;
        //}
    
        /*
        x=n;
        while(x<n1)
        {
            cin>>arr2[n+1];
            arr2++;
            x++;
        }
        arr2=arr2_1;
        x=0;
    
    
        while(x<n1)
        {
            cout<<arr2[0]<<endl;
            arr2++;
            x++;
        }*/
    
    
        //FREEING THE MEMORY POINTED MY THE 2 POINTERS
        if(isSizeChanged)
        {
            delete [] arr1;
            delete [] arr1_1;
        }
        else
            delete [] arr1;//YOU JUST NEED TO DELETE OR arr1 or arr1_1 
             //BECAUSE THEY ARE STILL POINTING TO THE SAME MEMORY LOCATION
    
        return 0;
    }