基类的指针数组;每次项目启动我都有不同的结果
Array of pointers of base class; every program launch I have different results
我有一项任务要创建四个类——一个基类、两个派生类和一个可以存储派生对象的动态数组。基类应该存储名称(一些字符串),派生类应该有其唯一的voice()函数。我的代码是:
#include <iostream>
class Pet
{
public:
char* name_;
virtual void voice(){}
};
class Dog : virtual public Pet
{
public:
Dog(char* str)
{
name_ = new char[strlen(str)];
for(int i=0; str[i] != 0; ++i)
{
name_[i] = str[i];
}
}
virtual void voice()
{
std::cout<<"I'm a dog! My name is "<<this->name_<<std::endl;
}
};
class Cat : virtual public Pet
{
public:
Cat(char* str)
{
name_ = new char[strlen(str)];
for(int i=0; str[i] != 0; ++i)
{
name_[i] = str[i];
}
}
virtual void voice()
{
std::cout<<"I'm a cat! My name is "<<this->name_<<std::endl;
}
};
class Pack
{
private:
Pet** pack_;
int num;
public:
Pack()
{
pack_ = new Pet*[0];
num = 0;
}
void add(Pet* a)
{
Pet** newpack = new Pet*[num+1];
for (int i = 0; i<num; ++i)
newpack[i] = pack_[i];
newpack[num] = a;
++num;
for (int i = 0; i<num; ++i)
pack_[i] = newpack[i];
delete [] newpack;
}
void voiceall()
{
for (int i=0; i<num; ++i)
pack_[i]->voice();
}
};
int main() {
Pack pack;
for (int i=0; i<6; ++i)
{
char* str;
std::cin.getline(str, 100);
if (i%2 == 0)
{
Dog* a = new Dog(str);
pack.add(a);
}
else
{
Cat* a = new Cat(str);
pack.add(a);
}
}
pack.voiceall();
return 0;
}
这段代码似乎有效,但令我惊讶的是,并不是每次启动它。使用相同输入的三分之一-一半的启动会导致错误(EXC_BAD_ACCESS),通常发生在pack_[i]->voice();
行Pack
类的voiceall()
函数中。我对这个从基派生的指针太陌生了,不明白哪里出了问题。
UPD:伙计们,我真的不能使用STL,因为我的老师教东西的方式很痛苦。
pack_ = new Pet*[0];
CCD_ 4指向大小为CCD_。
++num;
将num
递增到大于0
的数字。
for (int i = 0; i<num; ++i)
pack_[i] = newpack[i];
您对数组的访问超出了范围。这导致了不明确的行为。
要解决此问题,请不要访问超出其边界的数组。您可能打算分配一个大小为num
的数组,并将pack_
指向该数组。好吧,你确实分配了一个数组,但你永远不会更新pack_
,所以它的大小永远不会改变,然后你会删除新的更大的数组。我建议使用std::vector
来避免这样的错误(作为奖励,它也比你正在做的更高效)。
顺便说一下,您有许多内存泄漏。避免手动分配动态内存,使用std::string
和std::vector
可以轻松修复它们。
一个直接的崩溃源是您没有为输入分配任何内存——您正在读取一个未初始化的指针。
更换
char* str;
带有
char str[100];
您的名称数组也有一个元素太小;使用
name_ = new char[strlen(str) + 1];
strcpy(name_, str);
add
会立即删除需要存储所有元素的数组。
您还可以在旧数组的边界之外进行写入。
它应该更像这样:
void add(Pet* a)
{
Pet** newpack = new Pet*[num+1];
// Copy the old array to the new.
for (int i = 0; i<num; ++i)
newpack[i] = pack_[i];
// Add the new element to the new array.
newpack[num] = a;
++num;
delete [] pack_; // Delete the old array...
pack_ = newpack; // ... and use the new one instead.
}
相关文章:
- 为什么"do while"循环不断退出,即使条件计算结果为 false?
- valgrind-hellgrind与泄漏检查的结果不同
- 用C++20 fmt限制结果的总大小
- 如何返回一个类的两个对象相加的结果
- 如何创建一个空的全局类并在启动时实例化它
- 使用QProcess执行命令,并将结果存储在QStringList中
- 如果我std::dynamic_pointer_cast并且底层dynamic_cast的结果为null,那么返回的sh
- 在没有定义返回类型的函数中返回布尔值,并将结果保存在无错误的char编译中-为什么
- 序列化,没有库的整数,得到奇怪的结果
- 使用取消引用的指针的多态性会产生意外的结果.为什么?
- 在更改for循环的第三部分后,未使用for循环结果
- 使用++运算符会导致意外的结果
- 即使我读取了所有内容,在FIFO上打开的QSocketNotifier也会一直启动
- 为什么在逗号分隔符上下文中将预增量的结果强制转换为void
- C++Brute Force攻击函数不会返回结果
- 从C++启动matlab脚本并等待结果
- C++使用system()启动程序时没有得到所需的结果
- 基类的指针数组;每次项目启动我都有不同的结果
- 如何从c++应用程序启动java应用程序,传递参数并等待java应用程序的结果
- 如何用c++启动和恢复Maple的结果