2016-03-06 5 views
-2

Не ища ответа на этот вопрос, но какое-то направление будет оценено. Везде, где я смотрел, и все ответы, которые я пробовал, не решают проблему.Распределение динамической памяти C++, вызвавшее поврежденную кучу

У меня есть инструкции, в которых говорится: «Динамически выделять переменную точно, что вводит пользователь. Невозможно использовать переменную placeHolder (userInput [256}]), чтобы поймать вход. Append '\ 0' to end."

Мой первоначальный код:

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

Я знаю, что куча коррумпируется, я подозреваю, что от того, как я меняюсь выделенную память. Я не уверен, почему исправление не работает во всех учебниках таким образом.

+0

'(х^2)/2 = x' и' (ptrLength = Num) = (ptrLength == Num) '!. И вы освобождаете как исходные, так и новые буферы символов. Может быть, резиновая утка поможет. –

+0

@JamesRoot '(x^2)! = (X * x)' в C++ – MikeCAT

ответ

3

Вот как я представляю себе ваш разговор с your rubber duck бы пойти на данный момент:

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

Вы (разговор с вашей резиновой утки): Хорошо, так что выше сводится к , что я выделил буфер для десяти символов. userInput здесь указывает на десять символов, userInput[0] - userInput[9].

Резиновая утка: Хорошо.

Вы: А как num и ptrLength устанавливаются на значение 10.

Rubber Duck: имеет смысл для меня.

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

Вы: Итак, я проверяю, если следующий считанный символ является символом новой строки, если нет, то я место входа в userInput[ptrLength]

Rubber Duck: Подождите, что такое начальное значение ptrLength?

Вы: 10, как я только что сказал.

Rubber Duck: Но не просто сказать, что у вас есть только userInput[0] через userInput[9], выделенные для буфера, и писать что-то userInput[10], в этой точке, приведет к повреждению кучи.

Итак, каков ваш ответ на ваш вопрос резиновой утки?

1
  • userInput[ptrLength] находится вне диапазона и не должны быть доступны после того, как userInput = new char[ptrLength];.
  • Условие ptrLength = num не является критерием равенства, а назначением, и я думаю, это не то, что вы хотите.
  • Вы забыли обновить ptrLength после прочтения.
  • Вы удалили новый выделенный буфер и сделали его недоступным.
  • Вы должны удалить все, что вы создали, через new.
  • Вы должны использовать deleteдо assgning nullptr. Также используйте delete[] для того, что выделяется через new[].
  • После num = num*num;, num/2 обычно не будет прежним num. Вы должны вычислить квадратный корень, чтобы получитьот новых 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; 
} 
+0

Спасибо вам обоим. Duck Conversation помог столько же, сколько указать на другие ошибки моих способов. Я смог сфокусироваться и получить код, работающий за пределами аварийности. Очень ценю комментарии. – new2Me