c ++动态内存分配导致堆损坏

时间:2016-03-06 01:23:47

标签: c++ dynamic-memory-allocation heap-corruption

没有在这个问题上寻找答案,但是会有一些方向感激。我看过的每个地方和我尝试的所有答案都没有解决问题。

我有说明“动态地将变量分配给用户输入的内容。不能使用placeHolder变量(userInput [256}])来捕获输入。将'\ 0'追加到结尾。”

我的原始代码是:

int main(){

    char cont = 'y';
    char *userInput = nullptr;

    while (cont == 'y' || cont == 'Y')
    {

        int ptrLength = 0;
        userInput = new char[ptrLength];

        cout << "Please enter a word or phrase: ";//2. Asks the user to enter any string (any sequence of characters)
        while (cin.peek() != '\n'){
            cin >> userInput[ptrLength];
            ptrLength++;
        }
        //1. You must use a pointer to a C-string and dynamically allocate just enough memory to store all the characters entered by the user PLUS the ‘\0’ char than must be appended at the end of the C-string.

        userInput[ptrLength] = '\0';        

        cout << endl;
        myVowels(userInput, ptrLength);
        cout << endl << endl;
        //delete [] userInput; //deleting here breaks the program. Not sure why right now.
        //userInput = nullptr;
        //5. The user must be asked if he/she wants to continue entering values or quit.
        cout << endl << "To enter another phrase press Y. To exit press any key." << endl;
        cin >> cont;
        cin.clear();
        cin.ignore(256, '\n');
    }//end while cont = Y

    delete userInput;
    userInput = nullptr;
    system("pause");
    return 0;
}

更新代码:

int main(){

    char cont = 'y';
    char *userInput = nullptr;

    while (cont == 'y' || cont == 'Y')
    {

        int num = 10;
        int ptrLength = num;
        userInput = new char[ptrLength];
        char *temp = nullptr;

        cout << "Please enter a word or phrase: ";//2. Asks the user to enter any string (any sequence of characters)
//FIX I FOUND, BUT IT DOES NOT WORK AT ALL
        while (cin.peek() != '\n'){
            cin >> userInput[ptrLength];
            if (ptrLength = num){
                num *= num;
                temp = new char[num];
                for (int i = 0; i < num/2; i++)
                {
                    temp[i] = userInput[i];
                }
                delete [] userInput;
                userInput = temp;
                delete [] temp;
            }
        }
        //1. You must use a pointer to a C-string and dynamically allocate just enough memory to store all the characters entered by the user PLUS the ‘\0’ char than must be appended at the end of the C-string.

        userInput[ptrLength] = '\0';        

        cout << endl;
        myVowels(userInput, ptrLength);
        cout << endl << endl;

        //userInput = nullptr;
        //delete [] userInput; //This works, but by switching to nullptr I am not deleting the memory allocated. If I just have the delete with or without [] the program breaks. Tried with user input declared inside and outside of the WHILE statement. Heap is being corrupted.

        //5. The user must be asked if he/she wants to continue entering values or quit.
        cout << endl << "To enter another phrase press Y. To exit press any key." << endl;
        cin >> cont;
        cin.clear();
        cin.ignore(256, '\n');
    }//end while cont = Y

    delete userInput;
    userInput = nullptr;
    system("pause");
    return 0;
}

我知道堆已损坏,我怀疑我正在改变分配的内存。我不确定为什么修复不起作用,所有教程都是这样。

2 个答案:

答案 0 :(得分:3)

以下是我认为您与your rubber duck的对话此时会如何:

    int num = 10;
    int ptrLength = num;
    userInput = new char[ptrLength];
  

你(跟你的橡皮鸭说话):好的,所以上面归结为什么   是我为十个字符分配了一个缓冲区。 userInput在这里   指向十个字符userInput[0]userInput[9]

     

橡皮鸭:好的。

     

您:numptrLength都设置为值10。

     

橡皮鸭:对我有意义。

    while (cin.peek() != '\n'){
        cin >> userInput[ptrLength];
  

你:所以,我检查下一个字符是否是换行符,如果没有,我   将输入放在userInput[ptrLength]

中      

Rubber Duck:等等,ptrLength的初始值是多少?

     

你:10,正如我刚才所说。

     橡皮鸭:但你不是只说你只有userInput[0]   通过userInput[9],为你的缓冲区分配,并写作   此时userInput[10]的某些内容会破坏堆。

那么,你对这条橡皮鸭问题的答案是什么?

答案 1 :(得分:1)

  • userInput[ptrLength]超出范围,userInput = new char[ptrLength];后不得访问。
  • 条件ptrLength = num不是一个相等的测试,而是一个任务,我想这不是你想要的。
  • 您在阅读后忘了更新ptrLength
  • 您删除了新分配的缓冲区并使其无法使用。
  • 您应该删除通过new创建的内容。
  • 您必须在分配delete之前使用nullptr 。同时使用delete[]表示通过new[]分配的内容。
  • num = num*num;之后,num/2通常不会是之前的num。您必须计算平方根以从新num获取oid num

更正后的代码:

#include <iostream>
#include <cstdlib>
using std::cout;
using std::cin;
using std::endl;

void myVowels(const char *userInput, int ptrLength){
    cout << "myVowels(" << userInput << ", " << ptrLength << ")\n";
}

int main(){

    char cont = 'y';
    char *userInput = nullptr;

    while (cont == 'y' || cont == 'Y')
    {

        int num = 10;
        int ptrLength = 0;
        userInput = new char[num];
        char *temp = nullptr;

        cout << "Please enter a word or phrase: ";//2. Asks the user to enter any string (any sequence of characters)
        while (cin.peek() != '\n'){
            cin >> userInput[ptrLength++];
            if (ptrLength == num){
                int oldNum = num;
                num *= num;
                temp = new char[num];
                for (int i = 0; i < oldNum; i++)
                {
                    temp[i] = userInput[i];
                }
                delete [] userInput;
                userInput = temp;
            }
        }
        //1. You must use a pointer to a C-string and dynamically allocate just enough memory
        //   to store all the characters entered by the user PLUS the ‘\0’ char than must be
        //   appended at the end of the C-string.

        userInput[ptrLength] = '\0';

        cout << endl;
        myVowels(userInput, ptrLength);
        cout << endl << endl;

        delete [] userInput;
        userInput = nullptr;

        //5. The user must be asked if he/she wants to continue entering values or quit.
        cout << endl << "To enter another phrase press Y. To exit press any key." << endl;
        cin >> cont;
        cin.clear();
        cin.ignore(256, '\n');
    }//end while cont = Y

    system("pause");
    return 0;
}