【问题标题】:What is wrong with accessing this private variable of class by a private method? [closed]通过私有方法访问这个类的私有变量有什么问题? [关闭]
【发布时间】:2021-04-03 14:57:56
【问题描述】:

我要做的是将 csv 文件解析为内存的动态分配部分,该部分表示称为矩形的类的实例数组。

该项目由以下文件组成:

rectStructs.h:

#pragma once

struct rectangle_t
{
    int length;
    int width;
};

矩形.h

#pragma once

#include <iostream>

#include "rectStructs.h"

using namespace std;

class rectangle
{
public:
    rectangle(int length, int width);
    unsigned long int get_area();
private:
    rectangle_t _rectangle;
};

矩形.cpp

#include "rectangles.h"
#include <string> 

rectangle::rectangle(int RectLength, int RectWidth)
{
    _rectangle.length = RectLength;
    _rectangle.width = RectWidth;
}

unsigned long int rectangle::get_area()
{
    return _rectangle.length * _rectangle.width;
}

rectanglesSet.h

#pragma once

#include "rectangles.h"

#include <iostream>
#include <fstream>

class rectangleSet
{
public:
    rectangleSet(string path_sourceCSV);
    rectangle getRect(unsigned int RectIndex);
private:
    void readRectsFromCSV(rectangle** rectangles, string path_sourceCSV);
    rectangle* _rectangles;
    unsigned int _rectCount;
    rectangle _getRect(rectangle** rectangles, unsigned int RectIndex);
};

rectanglesSet.cpp

#define _CRT_SECURE_NO_DEPRECATE // For using fopen and strtok https://stackoverflow.com/questions/42412372/error-c4996-visual-studio-why-do-i-get-an-error-when-i-use-fopen-in-c

#include "rectanglesSet.h"

void rectangleSet::readRectsFromCSV(rectangle** rectangles, string path_sourceCSV)
{
    unsigned short int _linesCount = 0;

    //Parsing lt. https://stackoverflow.com/questions/56783258/parse-csv-into-dynamically-allocated-array-of-structures-ansi-89

    char c;

    FILE* fp;
    fp = fopen(path_sourceCSV.c_str(), "r");             /* Open the saleslines file */

    if (fp == NULL) {                              /* Crash if file not found */
        printf("Error - file not found\n");
    }

    c = getc(fp);
    while (c != EOF) {
        if (c == '\n') {
            _linesCount++;
        }
        c = getc(fp);
    }
    fclose(fp);

    cout << "Number of lines: " << _linesCount << endl;   //Debug

    *rectangles = (rectangle*)malloc((_linesCount + 1) * sizeof(rectangle));

    int _length;
    int _width;

    /* allocation of the buffer for every line in the File */
    char buf[1024];
    string tmp;

    if ((fp = fopen(path_sourceCSV.c_str(), "r")) == NULL)
    {
        printf("File could not be opened.\n");
    }
    int line = 0;
    while (fgets(buf, 1024, fp) != NULL)
    {
        if ((strlen(buf) > 0) && (buf[strlen(buf) - 1] == '\n'))
            buf[strlen(buf) - 1] = '\0';

        if (line > 0) // First line is header
        {
            tmp = strtok(buf, ",");
            _length = atoi(tmp.c_str());

            tmp = strtok(NULL, ",");
            _width = atoi(tmp.c_str());

            rectangles[line - 1] = new rectangle(_length, _width);

            //Debug
            cout << rectangles[line - 1]->get_area() << endl;
        }

        line++;
    }
    fclose(fp);

    //_rectCount = line - 1;

    cout << "Successfully parsed: " << path_sourceCSV << endl;
}

rectangleSet::rectangleSet(string path_sourceCSV)
{
    readRectsFromCSV(&_rectangles, path_sourceCSV);
}

rectangle rectangleSet::_getRect(rectangle** rectangles, unsigned int rectIndex)
{
    return *rectangles[rectIndex];
}

rectangle rectangleSet::getRect(unsigned int rectIndex)
{
    return _getRect(&_rectangles, rectIndex);
}

ma​​in.cpp

#include <iostream>
#include "rectangles.h"
#include "rectanglesSet.h"

int main()
{
    string str_SourceCSV = "C:\\rectangleList.csv";
    rectangleSet* _rectangleSet = new rectangleSet(str_SourceCSV);

    cout << _rectangleSet->getRect(1).get_area() << endl;
}

C:\rectangleList.csv

x,y
1,2
3,4
5,6

一切都很好,只要我在文件 rectanglesSet.cpp

中注释掉以下行
//_rectCount = line - 1;

应该写一个私有变量来保存动态数组_rectangles中的项目数。当我取消注释此行时,程序会因内存错误而崩溃。它运行到显示对象_rectangleSet 的第二项([1])。

这条线有什么问题?

_rectCount = line - 1;

【问题讨论】:

  • 您真的需要所有代码来重现您面临的问题吗?请张贴minimal reproducible example(强调minimal),说明您的问题。泰。
  • std::vector&lt;rectangle&gt;代替手动内存管理怎么样?
  • 请注意,该解决方案不属于该问题。它应该作为正确的答案发布。如果您想回答自己的问题,可以这样做。请重新上站tour

标签: c++


【解决方案1】:

你在这里分配一个矩形数组

*rectangles = (rectangle*)malloc((_linesCount + 1) * sizeof(rectangle));

但是你把它当作你在这里有一个矩形指针数组

rectangles[line - 1] = new rectangle(_length, _width);

上面一行的正确代码是

(*rectangles)[line - 1] = rectangle(_length, _width);

但是,即使使用此修复程序,您在技术上仍然是错误的,因为上述行分配给未初始化的内存(由malloc 返回)。所以第一行应该真正使用new 来确保矩形数组被正确初始化。

*rectangles = new rectangle[_linesCount + 1];

如果您不尝试自己进行内存管理,C++ 会容易得多。我建议您使用std::vector&lt;rectangle&gt; 而不是上面的代码。它也会更有效率,因为您可以使用vector::push_back 方法,这样您就不必预先计算行数,从而避免两次读取输入文件。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-11-15
    • 1970-01-01
    • 2015-09-25
    • 2012-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-13
    相关资源
    最近更新 更多