分配大小无效? C ++

时间:2016-02-02 01:11:51

标签: 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())行的函数Text :: Text(char * file)中收到错误。

现在,我调试并得出结论,错误导致分配大小无效。

当我进一步检查错误时,我注意到记录值会有一个荒谬的负数,例如-858993460!

我需要指出如何解决这个问题。

正在打开的文本文件非常大...

感谢。

1 个答案:

答案 0 :(得分:0)

首先,我们说您可以删除此代码的主要部分,如果您使用std::vector<std::string>作为handler成员,而不是{{1 }}

话虽如此,一个明显的错误是你有一个错误的复制构造函数。您没有复制传递给您的std::string*对象中的所有信息。您遗漏了Textfile_name成员,使他们未初始化。

此外,您的records成员变量设置不正确 - 您分配内存,然后再次将handler设置为指向传入对象{{1}的指针会员这完全是错误的。

复制构造函数应该分配一个新数组,然后将传入对象中的字符串复制到新对象的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];
    }
}

这使用copy / swap idiom。基本上所有这一切都是从传入的对象创建一个临时对象,并用delete [] handler;的内部交换其内部。然后临时对象以旧数据终止。