check string lifetime duration
check string lifetime duration
I am currently wondering if it is possible to check if a C-string has a static lifetime duration or not when only the pointer to the string is known.
Basically, I want to implement such a function:
bool isStaticString(const char *str)
{
//do magic stuff
}
and the results should be like this:
isStaticString("Hello World!"); //returns true
char str[5] = {''};
isStaticString(str); //returns false
Is there any portable way to implement such a function?
PS: I hope such question was not already asked,I did not really know what to search for. My title did not give me any results.
Are you asking about C or C++?
– melpomene
Jun 30 at 20:22
Writing to a string in read-only memory should throw an exception, which you can catch and ignore (I think). But the compiler won't compile it because your string is declared
const and so you'll have to override that in turn. It is also not portable: it depends on the target OS being able to construct read-only segments, and the compiler writing such strings into one.– usr2564301
Jun 30 at 20:23
const
@HolyBlackCat: writing into the string will trigger a fault if it's inside read-only memory. AFAIK both languages C and C++ themselves have no meta-information about strings (or other information), other than that they can be declared
const or not. Which (again AFAIK) you cannot test in run-time.– usr2564301
Jun 30 at 20:30
const
Possible duplicate of C test if variable is in read-only section
– Paul Ankman
Jun 30 at 20:38
1 Answer
1
It is impossible to do in a portable or reliable way.
However, pointers to static and read-only memory will typically be in a different memory segments than stack and dynamically-allocated memory, so you can check the difference between your pointer and some pre-allocated sample pointer, and kind of guess the memory layout.
#include <string>
#include <stdlib.h>
#include <stdio.h>
enum { CHAR_ARRAY_SIZE = 32 }; // Say no to magic constants
const char readonlyFossilizedBirdBones[CHAR_ARRAY_SIZE] = "Crow skeleton from taxidermist";
char globalVariableBirdBones[CHAR_ARRAY_SIZE] = "This pigeon was hit by a car";
bool askBirdBonesIfStringIsStatic(const char *str)
{
char freshStackBirdBones[CHAR_ARRAY_SIZE] = "Chicken wings from trash bin";
char * bloodyAllocBirdBones = (char *) malloc(CHAR_ARRAY_SIZE);
// strcpy() is unsafe, and strncpy() does not always zero-terminate the result
// but snprintf() is safe and will not trigger any static code analysis tools
snprintf(bloodyAllocBirdBones, CHAR_ARRAY_SIZE, "%s", "Sparrow caught by your cat");
bool divinationSaysStatic =
abs(readonlyFossilizedBirdBones - str) < abs(freshStackBirdBones - str) &&
abs(readonlyFossilizedBirdBones - str) < abs(bloodyAllocBirdBones - str) &&
abs(globalVariableBirdBones - str) < abs(freshStackBirdBones - str) &&
abs(globalVariableBirdBones - str) < abs(bloodyAllocBirdBones - str);
printf("Asking bird bones about '%s' at %p:n", str, str);
printf("Comparing to readonly %p global %p stack %p alloc %pn",
readonlyFossilizedBirdBones, globalVariableBirdBones,
freshStackBirdBones, bloodyAllocBirdBones);
printf("Result is %snn", divinationSaysStatic ? "favorable" : "unfavorable");
free(bloodyAllocBirdBones);
return divinationSaysStatic;
}
int main()
{
static char s1[CHAR_ARRAY_SIZE] = "Static string";
char s2[CHAR_ARRAY_SIZE] = "Short-lived stack string";
char * s3 = (char *) malloc(CHAR_ARRAY_SIZE);
snprintf(s3, CHAR_ARRAY_SIZE, "%s", "String allocated by malloc()");
askBirdBonesIfStringIsStatic(s1);
askBirdBonesIfStringIsStatic(s2);
askBirdBonesIfStringIsStatic(s3);
free(s3);
return 0;
}
And the results on my 64-bit Linux PC:
Asking bird bones about 'Static string' at 0x560815f27080:
Comparing to readonly 0x560815d26b00 global 0x560815f27060 stack 0x7ffe741d0b90 alloc 0x560816365c50
Result is favorable
Asking bird bones about 'Short-lived stack string' at 0x7ffe741d0be0:
Comparing to readonly 0x560815d26b00 global 0x560815f27060 stack 0x7ffe741d0b90 alloc 0x560816365c50
Result is unfavorable
Asking bird bones about 'String allocated by malloc()' at 0x560816365c20:
Comparing to readonly 0x560815d26b00 global 0x560815f27060 stack 0x7ffe741d0b90 alloc 0x560816365c50
Result is unfavorable
Please never ever use this code in production.
Why convert the
readonlyFossilizedBirdBones - str difference to int with abs(). It seems imaxabs() would be most likely to avoid signed integer overflow and/or truncation.– chux
Jul 1 at 18:29
readonlyFossilizedBirdBones - str
int
abs()
imaxabs()
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
No, and why do you need this?
– UnholySheep
Jun 30 at 20:19