Невозможно сделать портативным или надежным способом.
Однако указатели на статическую и доступную только для чтения память обычно находятся в разных сегментах памяти, чем стек и динамически выделенная память, поэтому вы можете проверить разницу между указателем и некоторым предварительно выделенным указателем выборки, а также предположить макет памяти.
#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 %p\n",
readonlyFossilizedBirdBones, globalVariableBirdBones,
freshStackBirdBones, bloodyAllocBirdBones);
printf("Result is %s\n\n", 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;
}
И результаты на моем 64-битном ПК с Linux:
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
Пожалуйста, никогда не используйте этот код в производстве.