Determine if a pointer is pointing to flash memory rather than global memory.

Is there any way to do this?

Print out the address?

A pointer can never point to flash memory. This is a Harvard architecture.

aarg:
A pointer can never point to flash memory. This is a Harvard architecture.

int PROGMEM i;

const __FlashStringHelper* str;

F(“string”)

INTP:
Print out the address?

How do I know what address range is flash memory and what address range is global memory?

boylesg:
int PROGMEM i;

const __FlashStringHelper* str;

F("string")

That points to data that has been transferred from flash to RAM. It's not in flash.

aarg:
A pointer can never point to flash memory. This is a Harvard architecture.

They are separate address spaces, but that's all. If you can't have a pointer to Flash what's
the program counter for instance? The PC gets pushed on the stack every function call.

Given just a value you can't know if its SRAM or Flash address, you have to keep track of that.

MarkT:
They are separate address spaces, but that's all. If you can't have a pointer to Flash what's
the program counter for instance? The PC gets pushed on the stack every function call.

Given just a value you can't know if its SRAM or Flash address, you have to keep track of that.

I believe the context was a C pointer, but I could be wrong. Even if you formed a pointer by accessing the PC value on the stack, you couldn't use it to access program code directly. If dereferenced, it would yield the contents of some nonsensical RAM location. It is because they are in different address spaces that any similarity is not useful.

In any case, this smacks of an XY problem.

You indeed can't use it directly to get data because of the Harverd architecture. But for all I know PROGMEM stuff just gives you a pointer to Flash but yeah, you have to use _P functions to access the data in which it's copied to RAM.

And no, there is no way of telling to what it's pointing. You have to remember it or make a new type for it to help you remember.

septillion:
You have to remember it or make a new type for it to help you remember.

That's what __FlashStringHelper* does.

Yes, but specific for strings :slight_smile: If the data isn't a string I would not use it.

What I mean is can I do something like this:

void CString::replace(void *strSearch, void *strReplace, int nStartFrom)
{
    if (/*strSearch and strReplace are both flash strings*/)
    { 
         
    }
    else if (/*strSearch is a flash string and strReplace is a normal string*/)
    { 
         
    }
    else if (/*strSearch is a normal string and strReplace is a flash string*/)
    { 
         
    }
    else if (/*strSearch and strReplace are both normal strings*/)
    { 
         
    }
}

No.

There is no way to 'sense' the real type behind a void* (or any other pointer).

You could write 4 different overloaded functions that handle all 4 different possibilities.

Whandall:
No.

There is no way to 'sense' the real type behind a void* (or any other pointer).

You could write 4 different overloaded functions that handle all 4 different possibilities.

I was trying to avoid having 4 segments of code that do exactly the same thing.

If you do too much of that then you end up with a code maintenance nightmare.

But if I can't avoid it in this case then I will just have to live with it I guess!

Then split of the part that's the same for all four and reuse it :slight_smile:

septillion:
Then split of the part that's the same for all four and reuse it :slight_smile:

I am between a rock and hard place Septillion. What you suggest is what I currently have, i.e. copy the flash strings to normals char* strings and then call the char*, char* version of my function. But that method loads memory and increases the risk of overrun and memory corruption.

I suspect that you cannot. It's like asking "if a variable contains the value 5, is it talking about 5 apples or 5 oranges"? If a pointer says "memory location 12345", that might mean 12345 into flash memory or 12345 into regular memory. there's no distinction - it's up to the programmer to know which variables are being used where.

I think you should be able to do anything with a flash string that you can do with a normal string. So there may be no need for you to differentiate in your function.

I’ve lost a bit what you actually want to do with the function… I see replace but at runtime you can’t replace parts of a flash string… But whatever you want to do, you might not need the complete string all the time.

For example, if you want to compare a string, you just need one char at a time. If it’s the same, move on and check again. No need to load the whole string in memory :slight_smile:

septillion:
I've lost a bit what you actually want to do with the function... I see replace but at runtime you can't replace parts of a flash string... But whatever you want to do, you might not need the complete string all the time.

For example, if you want to compare a string, you just need one char at a time. If it's the same, move on and check again. No need to load the whole string in memory :slight_smile:

I was using the existing string and mem functions to implement my algorithm, and they require the whole string to be in memory.