0

考虑以下简化代码:

typedef struct __attribute__ ((__packed__)) {
    int numberB;
    std::string strA;
} StructA;

typedef struct __attribute__ ((__packed__)) {
    int numberB;
    std::string strB;
} StructB;

char *ExampleClass::getBuffer(void){
  char* mBuf;
  int offset = 10;
  return mBuf+offset;
 }

void ExampleClass::ExampleFunction(StructA *A){
    StructB *B = (StructB *)getBuffer();
    B->numberB = A->numberA;
    B->strB = A->strA;
    return;
    }

这里有很多代码没有故意显示,但我相信我的问题的根源确实得到了证明:为什么我在尝试分配 B->strB = A->strA 时会出现分段错误?

谢谢

4

1 回答 1

2

In getBuffer(),mBufuninitialized,但是你添加offset到它,所以被return'ed 的指针是indeterminate。它当然没有指向有效的对象,这就是为什么访问的成员时StructB后续代码ExampleFunction()崩溃的原因。B从技术上讲,这是未定义的行为,所以任何事情都可能发生,不能保证崩溃。

但是,即使被初始化为足够大mBuf的有效缓冲区以容纳对象,在此代码中仍然没有实际构造的对象,因此并且不是有效对象。char[]StructBStructBB->numberBB->strA

getBuffer()需要做更多这样的事情:

char* ExampleClass::getBuffer(){
    char* mBuf = ...; // point to some char[] buffer that is at
                      // least 10+sizeof(StructB) in size, and
                      // isn't deallocated when getBuffer exits...
    int offset = 10;
    new(mBuf+offset) StructB;
    return mBuf+offset;
}

void ExampleClass::ExampleFunction(StructA *A){
    StructB *B = (StructB *)getBuffer();
    B->numberB = A->numberA;
    B->strB = A->strA;
    B->~StructB();
}

否则,ExampleFunction()将需要这样做:

char* ExampleClass::getBuffer(){
    char* mBuf = ...; // point to some char[] buffer that is at
                      // least 10+sizeof(StructB) in size, and
                      // isn't deallocated when getBuffer exits...
    int offset = 10;
    return mBuf+offset;
}

void ExampleClass::ExampleFunction(StructA *A){
    StructB *B = new(getBuffer()) StructB;
    B->numberB = A->numberA;
    B->strB = A->strA;
    B->~StructB();
}
于 2021-09-29T21:41:06.000 回答