如何理解指针的存储类型

我有一个家庭作业这个任务:

给定一个void** ptr_addr函数,如果 的存储类型*ptr_addr是静态或自动的,则返回 0,如果 的存储类型*ptr_addr是动态的,则返回 1 。代码的语言必须是 C。

问题是理论上我知道任务是关于什么的,但我不知道如何用代码检查以前的条件。

谢谢您的帮助!

回答

通常我不做作业,但在这种情况下我可能会例外。

请记住,我将要介绍的是可怕的代码。此外,它不符合您所述的要求 - 您必须为此进行调整。它也可能不符合您的讲师的期望:对于一个疯狂到足以分配此任务的讲师,我无法猜测他(她?它?)的期望。您可能会因为使用我介绍的技术或展示其他人的作品而受到指责。此外,会因为在 Stack Overflow 上展示这段代码而受到谴责,因为不,它不像可移植的或保证做任何事情,更不用说工作了。我不知道它是否适用于您的系统。

尽管如此,但愿上帝帮助我,我对其进行了测试,它确实在现代 Debian Linux 系统上“工作”。

#include <unistd.h>

extern etext, edata, end;

char *
mcat(void *p)
{
    int dummy;
    if(p < &etext)
         return "text";
    else if(p < &edata)
         return "data";
    else if(p < &end)
         return "bss";
    else if(p < sbrk(0))
         return "heap";
    else if(p > &dummy)
         return "stack";
    else return "?";
}

如果你编译它,你会得到很多警告,理论上可以使用一些显式强制转换来消除这些警告,但我认为这些警告实际上非常合适,考虑到这段代码的邪恶性。

它是如何工作的:至少在一些类 Unix 系统上,etextedataend是分别对应于程序文本、初始化数据和未初始化数据段结尾的魔术符号。 sbrk(0)为您提供一个指向传统实现malloc正在使用的堆顶部的指针。并且&dummy是堆栈底部的一个很好的近似值。

测试程序:

#include <stdio.h>
#include <stdlib.h>
    
int g = 2;
int g2;
    
int main()
{
    int l;
    static int s = 3;
    static int s2;
    int *p = malloc(sizeof(int));

    printf("g: %sn", mcat(&g));
    printf("g2: %sn", mcat(&g2));
    printf("main: %sn", mcat(main));
    printf("l: %sn", mcat(&l));
    printf("s: %sn", mcat(&s));
    printf("s2: %sn", mcat(&s2));
    printf("p: %sn", mcat(p));
}

在我的测试系统上打印

g: data
g2: bss
main: text
l: stack
s: data
s2: bss
p: heap


以上是如何理解指针的存储类型的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>