0

I have a class:

  1. Allocate blockSize*maxSize bytes of memory. Has a method which return ptr to free block of memory.
  2. I fill this block in main() for example (see usage below) and send it back to my class.

PROBLEM: How can I get position of sent me back address of initialized data? Because in main() I have void* ptr, not std::unique_ptr, and arithmetic with method memoryPool.get() not possible to use.

class A {
private:
    size_t maxBlocks;
    size_t blockSize;
    std::unique_ptr<unsigned char[]> memoryPool;

    void *getObjPtr(const size_t pos) const {
        return reinterpret_cast<void *>(memoryPool.get() + pos * blockSize);
    }
    
public:
    A(size_t blockSize, size_t maxBlocks) : blockSize(blockSize), maxBlocks(maxBlocks),
                                            memoryPool(new unsigned char[maxBlocks * blockSize]) {}

    void *getFree() {
        for (size_t i = 0; i < maxBlocks; ++i) {
            //check if this block not use (I cut this part)
            return getObjPtr(i);
        }
    }

    size_t getPosition(void *data) {
        //how can I get position of element? 
        // auto pos = ((char*)data - memoryPool.get()) / blockSize; - not works
        // ok there should be C++ style reinterpret_cast, but to short code I skip it
    }
}

Example of usage:

int main() {
    A queue(sizeof(int), 10);

    int *a = static_cast<int *>(queue.getFree());
    *a = 4;
    auto pos = queue.getPosition(a);//want to get position
}

What is proper way to do it? Without using std::unique_ptr in main?

Mike
  • 342
  • 4
  • 13
  • Please note that you may not assign a pointer to an array to `std::unique_ptr`, you need `std::unique_ptr`. It should be `std::unique_ptr memoryPool;` otherwise it will try to use `delete` instead of `delete[]`. – François Andrieux Dec 20 '20 at 17:15
  • When I look at `getPosition()`, I wonder what it does. Could you document what semantics it has, what it requires and what guarantees it offers? Of course, I'm assuming a working implementation, but the question remains what it's requirements are. – Ulrich Eckhardt Dec 20 '20 at 17:17
  • @UlrichEckhardt In this example it just return the position of element in my memoryPool. For example, if I fill I-th free position after `getFree()` then I will get `pos = 4` after calling `getPosition(a)`. I suppose that it should just return difference between i-th address ptr and started address pointer / blockSize. – Mike Dec 20 '20 at 17:21
  • I still don't understand. Can you give an example or two? – Ulrich Eckhardt Dec 20 '20 at 17:24
  • 1
    `((unsigned char*)data - memoryPool.get()) / blockSize` looks like it should in fact work. What do you mean when you say "not works" - what outcome do you expect, and what do you observe instead? – Igor Tandetnik Dec 20 '20 at 17:32
  • @IgorTandetnik Yes, you are right, thank you, I'm so inattentive – Mike Dec 20 '20 at 17:34
  • @FrançoisAndrieux Hmm, I roughly understood what you are talking about, but could advice, where can I read about? I thought that I allocate a big space `blocksize*blockCount` of 1 bytes, and because of `unique_ptr` it will deletes on a whole. Because it's not array, it space where I get access by knowing only me – Mike Dec 20 '20 at 17:38
  • @Mike If you assign the result of `new[]` to `unique_ptr` it has to be a `unique_ptr`. If you assign the result of `new` is has to be `unique_ptr`. See https://en.cppreference.com/w/cpp/memory/unique_ptr – François Andrieux Dec 20 '20 at 17:40
  • @Mike Or maybe the information you are missing is https://stackoverflow.com/questions/2425728/delete-vs-delete-operators-in-c – François Andrieux Dec 20 '20 at 17:41
  • 1
    This doesn’t address the question, but you can (and should) remove that `reinterpret_cast` in `getObjPtr`. Every pointer type can be implicitly converted to `void*`. – Pete Becker Dec 20 '20 at 18:48

1 Answers1

2

When I compile your code with Visual C++ 2019, I get this error:

error C2440: '-': cannot convert from 'unsigned char *' to 'char *'

If I change your code to cast to unsigned char* as per the error message, then it compiles:

auto pos = ((unsigned char*)data - memoryPool.get()) / blockSize;

Whether that does what you intend - well, it appears to, but you haven't clearly specified what getPosition does, so I can only guess.

Please post the error message in the future, not just say it doesn't work! It'll help us help you.

Tumbleweed53
  • 1,491
  • 7
  • 13