我可以将十六进制字符串作为地址传递给 C 中的函数吗?

Can I pass a hexadecimal string as an address to a function in C?

我试图将六进制字符串作为地址传递给函数作为参数。但我不知道我可以合法访问哪个地址。所以我使用了一个变量并得到了它的地址,希望我能知道我的进程可以使用的地址。但它没有用。我遇到了分段错误 11。谁能解释一下为什么?

这是我的代码:

#include <stdio.h>

void print_something(char *s) {
    printf("I was here\n");
    while (*s) {
        printf("%c", *s);
        s++;
    }
    printf("\n");
}

int main() {
    char a = 48;
    printf("%p\n", &a);
    print_something((char *) 0x7ffeec6a1b5b);
    return 0;
}

这就是我执行它时得到的结果:

0x7ffee31ecb5b
I was here
Segmentation fault: 11

Can anybody please explain me why?

这仅仅是因为操作系统告诉您的程序它试图访问不允许访问的内存。您可以在此处阅读有关它的详细信息:What is a segmentation fault?

除非您正在编写非常具体的代码,例如 os 内核或编码嵌入式系统或类似的东西,否则您永远不应该直接使用内存地址。并且没有可移植的方法来找出您可以访问哪些地址。

"I'm trying to figure out whether the compiler can understand if I give a hexa-string address to a function which requires a pointer as an argument."

"If I pass to the function print_something() a value like &a. It will work. But if I pass to it a value like 0x7ffeec6a1b5b. Does it know that it is an address and accesses this memory block have this address?"

编译器不知道也不关心传递的地址值是否表示有效的内存地址。它只是检查指针的赋值是否正确完成。

另外 0x7ffeec6a1b5b 也不是“六角串”。是整型常量,需要转换成要赋值的指针类型:

但是如果您稍后尝试通过取消引用指针来使用硬编码值访问此内存位置,它会调用 undefined behavior,如果地址无效或已被使用(很可能是这种情况)。

分段错误表示内存分配或内存访问未正确完成。 C 标准没有明确提及分段错误,因为它们取决于实现。它只是对未定义的行为进行分类。

内存地址通常由操作系统提供给请求程序。

作为程序员,您在大多数情况下不应该关心特定对象的确切存储位置,并且您不应该尝试在代码中使用任何特定的地址值,除非您为嵌入式系统编写代码你在哪里可以确定你编码的地址space。

所以回答你的问题:

Can I pass a hexa string as an address to a function as an argument in C?

当然可以。但是执行任何将该字符串或更好的整数作为地址的操作很可能会导致未定义的行为。如果它为您的特定系统定义得很好,您的程序仍然是不可移植的。所以一般来说,这样做没有多大意义(排除例外)。


旁注:

  • printf("%p\n", &a); 也是严格意义上的未定义行为。参数指针需要转换为 void * -> ``printf("%p\n", (void*) &a);`

是的,您可以提供一个十六进制数并将其转换为指针。但问题是,如果你应该,并且(除非,也许,如果你正在黑客攻击某些东西,在非常奇特的情况下),答案是绝对不.

您遇到分段错误是因为您告诉您的进程访问一个可能甚至没有映射到您的进程中的虚拟内存地址,即使是,您也可能不允许访问它,所以OS 保护您免于造成混乱并简单地杀死您的进程。