指针地址跨越各种平台

Ema*_*uel 0 c error-handling pointers void-pointers memory-address

在C中编码时的常见情况是编写返回指针的函数.如果在运行期间写入函数内发生某些错误,NULL可能会返回以指示错误.NULL只是特殊的内存地址0x0,除了表示特殊条件的出现之外,它从不用于任何东西.

我的问题是,是否有任何其他特殊的内存地址永远不会用于用户态应用程序数据?

我想知道这个的原因是因为它可以有效地用于错误处理.考虑一下:

#include <stdlib.h>
#include <stdio.h>

#define ERROR_NULL 0x0
#define ERROR_ZERO 0x1

int *example(int *a) {
    if (*a < 0)
        return ERROR_NULL;
    if (*a == 0)
        return (void *) ERROR_ZERO;
    return a;
}

int main(int argc, char **argv) {
    if (argc != 2) return -1;
    int *result;
    int a = atoi(argv[1]);
    switch ((int) (result = example(&a))) {
        case ERROR_NULL:
            printf("Below zero!\n");
            break;

        case ERROR_ZERO:
            printf("Is zero!\n");
            break;

        default:
            printf("Is %d!\n", *result);
            break;
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

知道用户地应用程序永远不会使用的一些特殊地址范围可以有效地用于更有效和更清洁的条件处理.如果您了解这一点,它适用于哪些平台?

我猜跨距将是特定于操作系统的.我最感兴趣的是Linux,但对OS X,Windows,Android和其他系统也很有用.

das*_*ght 5

NULL只是特殊的内存地址0x0,除了表示特殊条件的出现之外,它从不用于任何东西.

这不完全正确:有些计算机NULL指针在内部不是零(链接).

是否有任何其他特殊的内存地址永远不会用于用户态应用程序?

甚至NULL不是普遍的; 考虑到用C编程的不同平台的数量,没有其他普遍未使用的内存地址,这并不奇怪.

但是,没有人会阻止您在内存中定义自己的特殊地址,将其设置为全局变量,并将其视为错误指示器.这将适用于所有平台,并且不需要特殊的地址位置.

在标题中:

extern void* ERROR_ADDRESS;
Run Code Online (Sandbox Code Playgroud)

在C文件中:

static int UNUSED;
void *ERROR_ADDRESS = &UNUSED;
Run Code Online (Sandbox Code Playgroud)

此时,ERROR_ADDRESS指向全局唯一的位置(即UNUSED,定义它的编译单元的本地位置),您可以在测试指针中使用它来进行相等.