2017-09-23 77 views
-4

固定和低於的工作代碼沒有編譯錯誤,看起來沒有語法錯誤 - 但垃圾顯示?

下面是整個.cpp。有什麼想法爲什麼在過載void display(const Kingdom kingdoms[], size_t count)函數被調用時打印出純垃圾?

File Kingdom.h 
#ifndef KINGDOM_H 
#define KINGDOM_H 
#include <cstdlib> 
// TODO: sict namespace 
namespace sict 
{ 
    // TODO: define the structure Kingdom in the sict namespace 

     struct Kingdom { 
      char m_name[32]; 
      int m_population; 
     }; 
     // TODO: declare the function display(...), 
     //   also in the sict namespace 
     void display(const Kingdom& pKingdom); 
     void display(const Kingdom kingdoms[], size_t count); 
} 


#endif 

File Kingdom.cpp 
#include <iostream> 
#include <cstdlib> 
#include "Kingdom.h" 
using namespace std; 
// TODO: the sict namespace 
namespace sict 
{ 
    // TODO:definition for display(...) 

    void display(const Kingdom& pKingdom) { 
     cout << pKingdom.m_name << ", " << "population " << pKingdom.m_population << endl; 
    } 

    void display(const Kingdom kingdoms[], size_t count) { 
     cout << "------------------------------" << endl; 
     cout << "Kingdoms of SICT" << endl; 
     cout << "------------------------------" << endl; 
     int pop = 0; 
     for (size_t i = 0; i < count; i++) { 
      cout << i + 1 << ". "; 
      display(kingdoms[i]); 
       pop += kingdoms[i].m_population; 
     } 
     cout << "------------------------------" << endl; 
     cout << "Total population of SICT: " << pop << endl; 
     cout << "------------------------------"; 
    } 
} 


    File main.cpp 
    #include <iostream> 
    #include <cstring> //for size_t definition 
    #include <vector> 
    #include "Kingdom.h" 

    using namespace std; 
    using namespace sict; 

    void read(Kingdom&); 

    int main() { 
     int count = 0; // the number of kingdoms in the array 

     // TODO: declare the pKingdom pointer here (don't forget to initialize it) 
     Kingdom *pKingdom = nullptr; 
     cout << "==========\n" 
      << "Input data\n" 
      << "==========\n" 
      << "Enter the number of Kingdoms: "; 
     cin >> count; 
     cin.ignore(); 

     if (count < 1) return 1; 

     // TODO: allocate dynamic memory here for the pKingdom pointer 
     pKingdom = new Kingdom[count]; 
     for (int i = 0; i < count; ++i) { 
      cout << "Kingdom #" << i + 1 << ": " << endl; 
      // TODO: add code to accept user input for Kingdom i 
      read(pKingdom[i]); 
     } 
     cout << "==========" << endl << endl; 

     // testing that "display(...)" works 
     cout << "------------------------------" << endl 
      << "The 1st Kingdom entered is" << endl 
      << "------------------------------" << endl; 
     display(pKingdom[0]); 
     cout << "------------------------------" << endl << endl; 

     // expand the array of Kingdoms by 1 element 
     count = count + 1; 
     Kingdom *cpy_pKingdom = nullptr; 
     // TODO: allocate dynamic memory for count + 1 Kingdoms 
     cpy_pKingdom = new Kingdom[count]; 
     // TODO: copy elements from original array into this newly allocated array 
     for (int i = 0; i < count; i++) { 
      cpy_pKingdom[i] = pKingdom[i]; 
     } 
     // TODO: deallocate the dynamic memory for the original array 
     delete[] pKingdom; 
     // TODO: copy the address of the newly allocated array into pKingdom pointer 
     pKingdom = cpy_pKingdom; 
     // add the new Kingdom 
     cout << "==========\n" 
      << "Input data\n" 
      << "==========\n"; 
     cout << "Kingdom #" << count << ": " << endl; 
      // TODO: accept input for the new element in the array 
      read(pKingdom[count - 1]); 
     cout << "==========\n" << endl; 

     // testing that the overload of "display(...)" works 
     display(pKingdom, count); 
     cout << endl; 

     // TODO: deallocate the dynamic memory here 
     //delete[] pKingdom; 
     //delete[] cpy_pKingdom; 
     getchar(); 
     return 0; 
    } 

    // read accepts data for a Kingdom from standard input 
    // 
    void read(Kingdom& pkingdom) { 
     cout << "Enter the name of the Kingdom: "; 
     cin.get(pkingdom.m_name, 32, '\n'); 
     cin.ignore(2000, '\n'); 
     cout << "Enter the number of people living in " << pkingdom.m_name << ": "; 
     cin >> pkingdom.m_population; 
     cin.ignore(2000, '\n'); 
+2

使用std :: vector!你不要複製你的數組! – 2017-09-23 19:03:23

+3

擴展你的數組的代碼是錯誤的。 –

+0

這並沒有解決這個問題,但是你真的需要'std :: endl'做的額外的東西嗎? ''\ n''結束一行。 –

回答

0

明顯違規線(可能有其他人)是

cpy_pKingdom = new Kingdom[count + 1]; 
cpy_pKingdom = pKingdom; 
delete[] pKingdom; 
pKingdom = cpy_pKingdom; 

分配cpy_pKingdom = pKingdom是一個指針分配,並且不復制任何陣列。它也會丟棄新表達式的結果,並且表示cpy_pKingdompKingdom都具有pKingdom所具有的原始值。

delete [] pKingdom然後釋放存儲器指向pKingdom這也是內存cpy_Kingdom指向(因爲前述分配cpy_pKingdom = pKingdom的)。

這四條線的淨效果是new Kingom[count + 1]泄漏(它被分配,永遠不會釋放,但還無法訪問)和兩個pKingdom和解除分配內存cpy_pKingdom點。

更糟糕的是,那做任何事情與pKingdom下面的語句是

read(pKingdom[count + 1]); 

從文件到不存在的pKingdom[count + 1]讀取數據。並且請記住 - 即使先前的代碼已使pKingdom指向由new Kingdom[count + 1]分配的內存 - 這將會寫入該內存的末尾。還有未定義的行爲。

然後我們得到

display(pKingdom, count); 

將訪問同樣不存在的內存來打印出的數據存在。

在此處顯示垃圾是代碼中一個或多個未定義行爲實例的次要結果。