检查字符串生存期

时间:2018-06-30 20:18:32

标签: c string lifetime

我目前正在想,当仅知道指向字符串的指针时,是否可以检查C字符串是否具有静态生存期。

基本上,我想实现这样的功能:

bool isStaticString(const char *str)
{
    //do magic stuff
}

,结果应该是这样的:

 isStaticString("Hello World!"); //returns true

 char str[5] = {'\0'};
 isStaticString(str); //returns false

有没有可移植的方式来实现这种功能?

PS:我希望这样的问题没有被问到,我真的不知道要搜索什么。我的头衔没有给我任何结果。

1 个答案:

答案 0 :(得分:0)

不可能以便携式或可靠的方式进行。

但是,指向静态和只读内存的指针通常位于与堆栈和动态分配的内存不同的内存段中,因此您可以检查指针与某些预分配的样本指针之间的区别以及猜测内存布局。

#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 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

请永远不要在生产中使用此代码。