2016-02-02 71 views
1

我有三個文件:分配大小無效? C++

Text.h

#include <string> 

namespace w3 
{ 
    class Text 
    { 
     std::string file_name; 
     std::string* handler; 
     int records; 

    public: 
     Text(); 
     Text(char*); 
     size_t size() const; 
     Text(const Text&); 
     Text& operator=(const Text&); 
     Text(Text&&); 
     Text&& operator=(Text &&); 
     ~Text(); 
    }; 
} 

Text.cpp

#include <iostream> 
#include <string> 
#include <fstream> 
#include <cstring> 
#include "Text.h" 

namespace w3 
{ 
    Text::Text() 
    { 
     file_name = ""; 
     handler = nullptr; 
     records = 0; 
    } 

    Text::Text(char* file) 
    { 
     file_name = file; 

     if (file[0]='\0') 
     { 
      file_name=" "; 
      std::cout << "can not find file name !!" <<std::endl; 
     } 
     else 
     { 
      std::fstream f(file_name); 
      std::string line; 

      if (f.is_open()) //ERROR 
      { 
       while (std::getline(f,line,'\n')) 
       { 
        records++; 
       } 
      } 
      else 
      { 
       std::cout << "file not open !!" <<std::endl; 
      } 

      std::string* handle = new std::string[size()]; 

      f.clear(); 
      f.seekg(0,std::ios::beg); 

      int counter = 0; 

      while (std::getline(f,line,'\n')) 
      { 
       if (counter != records) 
       { 
        handle[counter]=line; 
        counter++; 
       } 
      } 
     } 
    } 

    size_t Text::size() const 
    { 
     return (size_t)records; 
    } 

    Text::Text(const Text& src) 
    { 
     std::string file_name = src.file_name; 

     int no_of_rec = src.records; 

     if (src.handler != nullptr) 
     { 
      handler = new std::string[src.size()]; 
      handler = src.handler; 
     } 
     else 
     { 
      handler = nullptr; 
     } 
    } 

    Text& Text::operator=(const Text& src) 
    { 
     if (this != &src) 
     { 
      int no_of_rec = src.records; 

      std::string file_name = src.file_name; 

      if (src.handler != nullptr) 
      { 
       handler = new std::string[src.size()]; 
       handler=src.handler; 
      } 
      else 
      { 
       handler = nullptr; 
      } 
     } 
     return *this; 
    } 

    Text::Text(Text&& src) 
    { 
     file_name=src.file_name; 

     handler = src.handler; 

     records = src.records; 

     src.file_name = " "; 
     src.handler = nullptr; 
     src.records = 0; 
    } 

    Text&& Text::operator=(Text&& src) 
    { 
     if (&src != this) 
     { 
      file_name = src.file_name; 

      handler = src.handler; 

      records = src.records; 

      src.file_name = " "; 

      src.handler = nullptr; 

      src.records = 0; 

     } 
     return std::move(*this); 
    } 

    Text::~Text() 
    { 
     //delete [] handler; 
    } 
} 

w3.cpp

#include <iostream> 
#include <iomanip> 
#include <utility> 
#include <ctime> 
#include "Text.h" 
#define TIME(start, end) double((end) - (start))/CLOCKS_PER_SEC 

int main (int argc, char* argv[]) { 
    if (argc == 1) { 
     std::cerr << argv[0] << ": missing file operand\n"; 
     return 1; 
    } 
    else if (argc != 2) { 
     std::cerr << argv[0] << ": too many arguments\n"; 
     return 2; 
    } 
    std::clock_t cs, ce; 
    { 
     std::cout << std::fixed << std::setprecision(3); 
     cs = std::clock(); 
     w3::Text a; 
     ce = std::clock(); 
     std::cout << "Constructor  " << TIME(cs, ce) << " seconds"; 
     std::cout << " - a.size = " << a.size() << std::endl; 

     cs = std::clock(); 
     w3::Text b(argv[1]); 
     ce = std::clock(); 
     std::cout << "Constructor  " << TIME(cs, ce) << " seconds"; 
     std::cout << " - b.size = " << b.size() << std::endl; 

     cs = std::clock(); 
     a = b; 
     ce = std::clock(); 
     std::cout << "Copy Assignment " << TIME(cs, ce) << " seconds"; 
     std::cout << " - a.size = " << a.size() << std::endl; 

     cs = std::clock(); 
     a = std::move(b); 
     ce = std::clock(); 
     std::cout << "Move Assignment " << TIME(cs, ce) << " seconds"; 
     std::cout << " - a.size = " << a.size() << std::endl; 

     cs = std::clock(); 
     w3::Text c = a; 
     ce = std::clock(); 
     std::cout << "Copy Constructor " << TIME(cs, ce) << " seconds"; 
     std::cout << " - c.size = " << c.size() << std::endl; 

     cs = std::clock(); 
     w3::Text d = std::move(a); 
     ce = std::clock(); 
     std::cout << "Move Constructor " << TIME(cs, ce) << " seconds"; 
     std::cout << " - d.size = " << d.size() << std::endl; 

     cs = std::clock(); 
    } 
    ce = std::clock(); 
    std::cout << "Destructor  " << TIME(cs, ce) << " seconds\n"; 
} 

我在函數文本得到一個錯誤:: if(f.is_open())行的文本(char *文件)。

現在,我調試並得出結論,錯誤導致無效的分配大小。

當我進一步檢查錯誤時,我發現記錄值會有一個荒謬的負數,例如-858993460!

我需要指導如何解決這個問題。

正在打開的文本文件是一個非常大的文件...

謝謝。應該說你能消除這種代碼的主要部分,再加上有,如果你使用std::vector<std::string>作爲handler成員發生錯誤的可能性很小,而不是std::string*

+0

'正在打開的文本文件是一個非常大的文件...'超過2GB? (隨機猜測,還沒有看過代碼) – deviantfan

+1

爲什麼不使用'std :: vector '而不是原始數組? – crashmstr

+1

@Shrooms您正在創建本地'handle'變量,並且不會分配給'handler'成員。 – Arpegius

回答

0

讓我們開始。

話雖如此,一個明顯的錯誤是你有一個錯誤的複製構造函數。您沒有複製傳遞給您的Text對象的所有信息。您遺漏了file_namerecords成員,使其未初始化。

此外,您的handler成員變量設置不正確 - 您分配內存,然後再將this->handler設置爲指向傳入對象的handler成員的指針。這完全不正確。

複製構造函數應分配一個新數組,然後將字符串從傳入對象複製到新對象的handler成員。

你的拷貝構造函數應該是這個樣子:

Text::Text(const Text& src) : file_name(src.file_name), 
           records(src.records), 
           handler(nullptr) 
{ 
    if (src.handler) 
    { 
     handler = new std::string[src.records]; 
     for (size_t i = 0; i < src.records; ++i) 
      handler[i] = src.handler[i]; 
    } 
} 

一旦你有了這個,請從析構函數的註釋 - delete [] handler;應該是註釋。

一旦這些全部完成,賦值運算符很簡單:

#include <algorithm> 
//... 
Text& operator=(const Text& src) 
{ 
    Text tmp(src); 
    std::swap(tmp.handler, handler); 
    std::swap(tmp.records, records); 
    std::swap(tmp.file_name, file_name); 
    return *this; 
} 

它使用copy/swap idiom。基本上所有這一切都是從傳入的對象中創建一個臨時對象,並用this的內部換出它的內部。然後臨時對象與舊數據一起死亡。