Simple Pointer/Reference question I can't figure out

I spend most of my time in C# and I have never had a good grasp of pointers and references. I would appreciate any help.

For example I have the following:

std::vector<Memory<float>*> memories;
for (int i = 0; i < samplesPerBlock; i++) {
	Memory<float> memory(deviceGPU, fdmMeshN);
	Memory<float>* memPtr = &memory;

	memories.emplace_back(memPtr);
	for (int j = 0; j < fdmMeshN; j++) {
		memory[j] = 1;
	}
	DBG("memory " << memory[0] << " " << (*(memories[0]))[0] << " " << (*memPtr)[0]);
	
};
DBG("MEMORY 0 " << (*(memories[0]))[0]);

As expected the line:
DBG("memory " << memory[0] << " " << (*(memories[0]))[0] << " " << (*memPtr)[0]);
puts out 1 for each reading.

However after the for loop is done everything somehow goes to shit and DBG("MEMORY 0 " << (*(memories[0]))[0]); reads -1.9984e+18

How is this possible? It should also read 1.

This is a microcosm of the problem I’m trying to solve with structuring some of my openCL elements for buffer based processing.

Any direction on what I screwed up is very appreciated.

for (int i = 0; i < samplesPerBlock; i++) {
	Memory<float> memory(deviceGPU, fdmMeshN);

If you do this, the memory will be created & destroyed per loop (but you want to keep the memory). You may use std::unique_ptr. BTW, I am not sure whether frequent memory allocation on the audio thread will work for your case :innocent: perhaps it is unavoidable for GPU?

This Memory structure represents an equal amount of memory generated in parallel on the GPU and CPU. It is very handy for copying things back and forth.

Yeah I presumed something is getting garbage collected. But why? Doesn’t

	Memory<float> memory(deviceGPU, fdmMeshN);
	Memory<float>* memPtr = &memory;
	memories.emplace_back(memPtr);

mean the memPtr is copied into the vector and thus points to the memory object. That is not enough to keep it alive?

Can you show me any quick re-write that would work? I am honestly terrible at this. Thanks.

Yes it is. But the memory get destroyed per loop, i.e., the memories will become a vector of meaningless pointers outside the loop.

I would do this:

std::vector<std::unique_ptr<Memory<float>>> memories;
for (int i = 0; i < samplesPerBlock; i++) {
    memories.emplace_back(std::make_unique<Memory<float>>(deviceGPU, fdmMeshN);
1 Like

Thanks that is very helpful. Can I ask you one more follow up to extend the example?

This is the other major problem I always run into in these situations and never know what to do.

If I set up:

private:

	std::shared_ptr<Memory<float>> fdmG;
	std::shared_ptr<Memory<float>> fdmG_1;

Then:

std::vector<std::shared_ptr<Memory<float>>> memoryList;

memoryList.emplace_back(fdmG);
memoryList.emplace_back(fdmG_1);


		for (int i = 0; i < memoryList.size(); i++) {
			auto memPtr = std::make_shared<Memory<float>>(deviceGPU, fdmMeshN);
			memoryList[i] = memPtr;
			
			if (i == 0) {
				DBG(" FDMG LENGTH " << fdmG->length()); //DOESN'T WORK
				DBG(" 0 LENGTH " << memoryList[i]->length()); //WORKS

			}
		
		}

The memoryList gets a working pointer to the new Memory object. However, the fdmG object is still pointing at nothing. The whole point of the temporary memoryList object is I wanted to update the private pointers like fdmG without having to go through them one by one.

Is there any way to make this code update fdmG at the same time? Ie. from some type of list?

Hypothetically, if memoryList was 20+ entries long, I don’t want to update all the private objects one by one. I want to put them in that big list and iterate through to make my life easier.

But this is not updating the core private elements. Do I need to make some type of reference list or what?

Any thought?

Or another question along these lines.

If I go:

std::vector<std::shared_ptr<Memory<float>>> memoryList;
fdmG = std::make_shared<Memory<float>>(deviceGPU, fdmMeshN);
memoryList.emplace_back(fdmG);
(*memoryList[0])[0] = 0; //error

//Exception thrown: read access violation.
//**this** was nullptr.

Why does this give me a memory access error? Bizarre no?

I hate pointers.

It seems that there is a typo in my previous post :sweat_smile: Anyway, I am not sure what does the Memory look like. Here is some code that works for me:

#include <iostream>
#include <vector>

class Memory {
public:
    std::vector<float> data;

    Memory(const size_t deviceGPU, const size_t fdmMeshN) {
        data.resize(deviceGPU * fdmMeshN);
    }

    const float& operator[](const size_t index) const {
        return data[index];
    }

    float& operator[](const size_t index) {
        return data[index];
    }
};

int main() {
    std::vector<std::unique_ptr<Memory>> memoryList;
    for (size_t i = 0; i < 10; ++i) {
        auto memPtr = std::make_unique<Memory>(3, 3);
        for (size_t j = 0; j < 9; ++j) {
            (*memPtr)[j] = 1.f;
        }
        memoryList.emplace_back(std::move(memPtr));
    }
    std::cout << (*memoryList[0])[0];
    return 0;
}
1 Like