【问题标题】:Expanding memory in a dynamically allocated pointer array在动态分配的指针数组中扩展内存
【发布时间】:2017-06-20 01:49:34
【问题描述】:

我试图在添加对象时扩展我的数组。但它不会起作用。我一直在寻找和寻找,但找不到问题......对于受过训练的眼睛来说,这并不困难,所以我想我可以问你们。我有两个类,其中类Timber 链接到TimberRegister,但Timber 看不到TimberRegisterTimberRegister 可以看到它。我觉得给你看TimberRegister的cppfile和主文件应该就够了,因为我很确定其他文件没问题,应该不会影响错误,这似乎是toString不能写第三个对象,因为它没有内存。

#include "timberRegister.h"
#include <iostream>

int main() {

    TimberRegister oak("Oak");
    oak.addTimber("20x10", 4, 10.50);
    oak.addTimber("28x14", 4, 15.00);
    oak.addTimber("15x5", 2, 5);

    int nrOf = oak.getNrOfTimber();
    string* str = new string[nrOf];
    oak.getTimberAsString(str, nrOf);
    cout << oak.getTitle() << endl;
    for (int i = 0; i < nrOf; i++) {
    cout << str[i] << endl;
    }

    return 0;
}
#include "timberRegister.h"

void TimberRegister::expand() {
    this->capacity += 10;
    Timber* *tmp = new Timber*[capacity];

    for (int i = 0; i < this->nrOfTimber; i++) {
        tmp[i] = this->timber[i];
    }
    delete[] this->timber;
    this->timber = tmp;
    this->initiate(this->nrOfTimber);
 }

 void TimberRegister::initiate(int from) {
     for (int i = 0; i < this->capacity; i++) {
        this->timber[i] = nullptr;
     }
 }

 void TimberRegister::freeMemory() {
 for (int i = 0; i < this->nrOfTimber; i++) {
        delete this->timber[i];
 }
    delete[] this->timber;
 }

 int TimberRegister::find(string dimension, int meters, double price) {
    int place = -1;
    Timber tmp(dimension, meters, price);

for (int i = 0; i < this->nrOfTimber && place == -1; i++) {
    if (*this->timber[i] == tmp) {
        place = i;
    }
}
return place;
}

TimberRegister::TimberRegister(string title) {
this->title = title;
this->nrOfTimber = 0;
this->capacity = 2;
this->timber = new Timber*[this->capacity];
for (int i = 0; i < capacity; i++) {
    this->timber[i] = nullptr;
}
this->initiate(this->nrOfTimber);
}

TimberRegister::TimberRegister(const TimberRegister &origObj) {
if (this != &origObj) {
    this->title = origObj.title;
    this->nrOfTimber = origObj.capacity;
    this->timber = new Timber*[origObj.capacity];
    for (int i = 0; i < origObj.nrOfTimber; i++) {
        this->timber[i] = new Timber(*origObj.timber[i]);
    }
    this->initiate(origObj.getNrOfTimber());
}
}

TimberRegister::~TimberRegister() {
this->freeMemory();
}

TimberRegister TimberRegister::operator=(const TimberRegister & origObj) {
this->freeMemory();

this->title = origObj.title;
this->nrOfTimber = origObj.nrOfTimber;
this->capacity = origObj.capacity;
this->timber = new Timber*[origObj.capacity];
for (int i = 0; i < origObj.capacity; i++) {
    this->timber[i] = new Timber(*origObj.timber[i]);
}
this->initiate(origObj.getNrOfTimber());

return *this;
}

bool TimberRegister::addTimber(string dimension, int meters, double price) {
bool added = false;

if (this->existTimber(dimension, meters, price) == false) {
    if (this->nrOfTimber >= this->capacity) {
        this->expand();
    }
    this->timber[nrOfTimber++] = new Timber(dimension, meters, price);
    added = true;
}
return added;
}

bool TimberRegister::removeTimber(string dimension, int meters, double    price) {
bool removed = false;
int tmp = -1;
tmp = this->find(dimension, meters, price);

if (tmp != -1) {
    delete this->timber[tmp];
    this->timber[tmp] = this->timber[--this->nrOfTimber];
    removed = true;
}
return removed;
}

bool TimberRegister::existTimber(string dimension, int meters, double price) {
bool found = false;
Timber tmp(dimension, meters, price);

for (int i = 0; i < nrOfTimber && found == false; i++) {
    if (*this->timber[i] == tmp) {
        found = true;
    }
}
return found;
}

int TimberRegister::getNrOfTimber() const {
return this->nrOfTimber;
}

string TimberRegister::getTitle() const{
return this->title;
}

void TimberRegister::setTitle(string title) {
this->title = title;
}

void TimberRegister::clear() {
freeMemory();
this->timber = new Timber*[capacity];
}

void TimberRegister::getTimberAsString(string arr[], int nrOf) const {
for (int i = 0; i < nrOf; i++) {
    arr[i] = this->timber[i]->toString();
}
}

【问题讨论】:

  • 你为什么不用std::vector
  • 谢谢 :) 但我不能使用它。我现在需要学会在没有向量的情况下做到这一点。
  • @Henke 然后创建自己的简单向量类(读取封装)并使用它,而不是像这样进行一次性编码。您的代码中到处都是new,确保为所有这些调用发出delete 将是一场噩梦。
  • @Henke 我看到你学过赋值运算符和复制构造函数。将其用于您的优势。创建您自己的管理内存的向量类——您已经学会了执行此操作的工具。一旦你这样做了,然后替换你正在执行 new[]delete[] 调用的所有代码,并使用你的向量类。
  • @Henke 为什么您的复制构造函数检查this 开始等于当前对象,而当前对象是全新的?另外,为什么您的赋值运算符不检查自赋值?它有严重的缺陷,并且可以通过编写一个 2 或 3 行 main 程序来证明它是有缺陷的。 TimberRegister oak("Oak"); oak.addTimber("20x10", 4, 10.50); oak = oak;

标签: c++ arrays class object expand


【解决方案1】:

但它不会起作用。我一直在寻找和寻找,但找不到问题。

我注意到一个问题:

void TimberRegister::initiate(int from) {
     for (int i = 0; i < this->capacity; i++) {
        this->timber[i] = nullptr;
     }
 }

在该函数中,您将创建所有指针nullptr。你需要使用:

void TimberRegister::initiate(int from) {
     for (int i = from; i < this->capacity; i++) { // i = from, not i = 0
        this->timber[i] = nullptr;
     }
 }

【讨论】:

    【解决方案2】:

    首先,就像 cmets 指出的那样:

    std::vector
    

    可能是更好的解决方案。

    其次,我建议统一缩进你的代码以使其更易于阅读。

    最后,(如果你的表总是以空指针结束)我认为这是问题所在:

     void TimberRegister::initiate(int from) {
     for (int i = 0; i < this->capacity; i++) {
        this->timber[i] = nullptr;
    

    i 不应该从from 开始吗?即int i = from

    【讨论】:

      猜你喜欢
      • 2014-02-26
      • 2013-10-04
      • 1970-01-01
      • 2018-06-23
      • 2015-06-19
      • 1970-01-01
      • 1970-01-01
      • 2021-04-15
      • 2019-06-24
      相关资源
      最近更新 更多