输出的逻辑错误

时间:2014-08-17 18:30:12

标签: c++ arrays pointers allocation

我正在研究一个使用指针创建动态数组的程序,然后重新分配它。

问题是程序运行成功但输出错误。任何帮助,将不胜感激。

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

2 个答案:

答案 0 :(得分:3)

有两个主要问题:第一个问题是您使用两个不同的系统进行内存分配。 newrealloc都会返回指针,但newrealloc不属于同一系统,不应混用。你要么使用C ++,要么使用C,不要混用。

第二个问题是当你第二次读入数据时,你没有重置arr2指向从上面的复制循环中分配数据的开始,所以你写的是界限。

此外,如果您决定采用C方式并使用mallocreallocfree,您应该知道realloc正是如此,它会重新分配现有的内存,包括复制数据,因此您不必进行手动复制。此外,为什么首先使用relloc(和复制),当你做的第一件事就是覆盖所有数据?


作为旁注,我认为你了解指针及其工作原理是好的,但是将来当你想使用“动态数组”时,你应该用std::vector来做。

答案 1 :(得分:0)

我修改了您的代码并对其进行了评论。我希望它可以帮到你:

#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;
}