How to find the relative address `FILE *`

To find out why I am doing what is described below, you can read this question. In short: for some reason, the library code asks for a function that is not defined by the corresponding class, my solution: extend the class as you wish, write down the requested function, and use my class.

I have a function void* advance(uint64_t nbytes)that will be called somewhere by some library code like memcpy(object.advance(nbytes), source, nbytes). From the inside advance(), I have access to FILE*where the results should be stored, so from what I understand, I should return a pointer that will have an address relative to the entire memory, but be inside FILE*so that the library code can be written accordingly.

What I have tried so far:

void* advance(uint64_t nbytes){
    return this->getFilePointer()->_IO_buf_base;
}

void* advance(uint64_t nbytes){
    return this->getFilePointer()->_IO_write_base;
}

Since I am not familiar with how the memory allocation for files works in general, I assumed that technically it should also be allocated, so I did this:

void* advance(uint64_t nbytes){
    char *ptr = new char [nbytes];
    fwrite(ptr,1,nbytes,this->getFilePointer());
    return this->getFilePointer()->_IO_write_base;
}

In my last example, I realized that for some reason, this->getFilePointer()->_IO_write_ptr - this->getFilePointer()->_IO_write_base == 125while nbytes == 9830525, therefore, it is obvious that something is wrong again ...

All of the above examples invoke segfault.

Is my logic correct i.e. does it make sense to do what I do? If so, how can I achieve the desired result?

ps I tried to make the question as short as possible, if you need any additional information, I provided it.

edits:

This is the code that calls advance()

void Bag::readMessageDataIntoStream(IndexEntry const& index_entry, Stream& stream) const {
    ros::Header header;
    uint32_t data_size;
    uint32_t bytes_read;
    switch (version_)
    {
    case 200:
    {
        decompressChunk(index_entry.chunk_pos);
        readMessageDataHeaderFromBuffer(*current_buffer_, index_entry.offset, header, data_size, bytes_read);
        if (data_size > 0)
            memcpy(stream.advance(data_size), current_buffer_->getData() + index_entry.offset + bytes_read, data_size);
        break;
    }
    case 102:
    {
        readMessageDataRecord102(index_entry.chunk_pos, header);
        data_size = record_buffer_.getSize();
        if (data_size > 0)
            memcpy(stream.advance(data_size), record_buffer_.getData(), data_size);
        break;
    }
    default:
        throw BagFormatException((boost::format("Unhandled version: %1%") % version_).str());
    }
}

Where Streamwill be my object that inherits from this one

I tried this too:

char *ptr;
void* advance(uint64_t nbytes){
        ptr = new char [nbytes];
        return ptr;
}

, , , , .

+4
1

, .

FILE, . . , FILE (, , segfault/GPF).

, , (memcpy). memcpy .

:

advance() . ( advance()) , . , ( - , , ) , , () . - :

class AutoWrite {
 public:
  AutoWrite(FILE* file): file_(file), buffer_(nullptr), size_(0) {}

  ~AutoWrite() {
    flush_last();
    fclose(file_);
  }

  void* advance(uint64_t nbytes) {
    flush_last();
    buffer_ = new char[nbytes];
    size_ = nbytes;
    return buffer;
  }

  void flush_last() {
    if (size_ > 0) {
      fwrite(static_cast<void*>(buffer_), 1, size_, file);
      size_ = 0;
      delete[] buffer_;
    }
  }

 private:
  FILE* file_;
  char* buffer_;
  uint64_t size_;
};

"": , , ( ).

PS. FILE. . , . .

+4

All Articles