繁体   English   中英

C ++中的指针对象

[英]Pointer object in C++

我有一个非常简单的类,如下所示:

class CHeader
{
public:
  CHeader();
  ~CHeader();
  void SetCommand( const unsigned char cmd );
  void SetFlag( const unsigned char flag );
public:
  unsigned char iHeader[32];    
};

void CHeader::SetCommand( const unsigned char cmd )
{
    iHeader[0] = cmd;
}

void CHeader::SetFlag( const unsigned char flag )
{
    iHeader[1] = flag;
}

然后,我有一个方法,将指向CHeader的指针作为输入,如下所示:

void updateHeader(CHeader *Hdr)
{

   unsigned char cmd = 'A';
   unsigned char flag = 'B';

   Hdr->SetCommand(cmd);
   Hdr->SetFlag(flag);
   ...
}

基本上,此方法只是将一些数组值设置为某个值。

然后,我创建一个指向类CHeader的对象的指针,并将其传递给updateHeader函数:

CHeader* hdr = new CHeader();
updateHeader(hdr);

这样做时,程序在执行Hdr-> SetCommand(cmd)行时便崩溃了。 任何人看到问题,任何输入将不胜感激

当您撞车时,就像犯罪调查员一样:调查犯罪现场。

  • 您从环境中获得的信息是什么(访问冲突?任何调试消息?* Hdr处的内存是什么样的?...)
  • 传入的Hdr指针有效吗?

然后使用逻辑推论,例如:

  • Hdr的取消引用导致访问冲突
  • =>传递的Hdr指向无效的内存
  • =>内存以无效开头(错误的指针传入),或者内存无效(对象在传入指针之前被删除,或者有人在内存上绘画)
  • ...

可能是SEGFAULTing。 检查指针。

  • 您添加一些源代码
  • 您对事物在另一台机器上运行的评论
  • 您使用术语“标志”和“ cmd”以及一些非常小的数据类型的事实

让我假设目标计算机的容量非常有限,我建议测试new CHeader的结果的有效性:如果系统资源不足,则结果指针将不会引用有效内存。

您提供的代码没有错。

输入“ updateHeader”函数后,是否确定创建的指针具有相同的地址? 可以肯定的是,在new()记下地址之后,用已知的唯一值(例如0XDEAD)填充内存sizeof(CHeader),然后追溯到updateHeader函数,确保所有内容均相等。

除此之外,我想知道这是否是对齐问题。 我知道您使用的是8位值,但是请尝试将数组更改为无符号整数或长整型,看看是否遇到相同的问题。 您在什么架构上运行它?

您的代码看起来不错。 我看到的唯一潜在问题是您在类中声明了CHeader构造函数和析构函数,但未显示任何一个的实现。 我想您只是省略了显示这些内容,否则链接器应该抱怨(如果我在VC ++ 6中复制此项目,则构造函数会出现“无法解决的外部错误”。它也应该显示相同的错误)析构函数,如果您有...删除hdr; ...代码中的语句)。

但是实际上没有必要为类中声明的每个方法都实现,除非方法实际上将要被调用(任何未实现的方法将被编译器/链接器忽略(如果从未调用)。 当然,对于一个对象,在实例化该对象时必须调用其中一个构造函数-这就是如果您省略向类中添加任何构造函数的原因,则编译器将为您创建默认构造函数的原因。 但是,如果不执行声明的构造函数,则编译器将上面的代码编译/链接将是一个严重的错误,因此,如果这是导致您出现问题的原因,我将感到非常惊讶。

但是,您描述的症状绝对听起来像是传递给updateHeader函数的'hdr'指针无效。 原因是在updateHeader函数调用之后第一次取消引用此指针是在... Hdr-> SetCommand(cmd);中。 ...通话(您说崩溃了)。

我只能想到这种无效指针的两种可能情况:

a。)您的堆有问题,并且在创建“ hdr”对象时使用“ new”运算符分配内存失败。 也许您的堆空间不足。 在某些嵌入式环境中,您可能还需要提供“新”和“删除”运算符的“自定义”版本。 最简单的检查方法(您应该始终这样做)是在分配后检查指针的有效性:

CHeader* hdr = new CHeader();
if(hdr) {
    updateHeader(hdr);
}
else
    //handle or throw exception...

当“ new”失败时,正常的行为实际上应该是引发异常-因此,以下代码也可以满足该要求:

try{
CHeader* hdr = new CHeader();
} catch(...) {
//handle or throw specific exception i.e. AfxThrowMemoryException() for MFC
}
if(hdr) {
updateHeader(hdr);
}
else
//handle or throw exception...
}

b。)您使用的是一些较旧的(可能是16位和/或嵌入式)环境,您可能需要在堆上创建的对象使用FAR指针(包括SEGMENT地址)。

我怀疑您需要提供有关环境以及编译器的更多详细信息,以获得有关此问题的任何有用反馈。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM