【问题标题】:assign address of char pointer to int将 char 指针的地址分配给 int
【发布时间】:2020-12-16 04:51:17
【问题描述】:

我有一个获取整数作为参数的函数。我想向它发送一个 char 数组的地址,然后从它的地址打印数组。我的意思是:

void printSomeThing(int x){
    printf("Variable is: %s\n", /*What to type here?*/);
    //I want this printf to write "file.txt"
}

....

int main(){
    char filename[10] = "file.txt";
    char *filePointer = filename;  //So it points to filename[0]'s address.
    int x = /*How to convert the address of the pointer (or the char array) to an integer?*/
    printSomeThing(x);
}

所以,我想将 char 数组的地址发送给函数并打印该地址的值。

注意:我无法更改 printSomeThing 参数。它必须是int

【问题讨论】:

  • 您可以尝试将指针转换为int,然后再转换回char *,但它可能不起作用(未定义的行为)。在许多系统上这是不可能的,例如指针为 64 位但 int 仅为 32 位的 64 位系统。代码会编译,但运行时很可能会崩溃。
  • 为什么需要这样做?您要解决的实际问题是什么?将指针值传递给函数的方法是使用指针类型的参数。
  • 首先要做的是在你的代码中添加printf("%zu %zu\n", sizeof(filePointer), sizeof(x));。如果它打印两个不同的数字,那么您根本无法做到您所希望的。
  • @NateEldredge 是对的。正确的方法是将指针指向 C99 中提供的 uintptr_t(如果我错了,请有人纠正我)。除此之外,将指针转换为整数通常会导致坏事发生。

标签: arrays c pointers char


【解决方案1】:

在指针地址和整数之间转换的正确方法是使用uintptr_t 整数类型。这是一种保证足够大以容纳地址的类型(与int 不同)。此代码相当安全且可移植:

#include <stdio.h>

void printSomeThing(uintptr_t x){
    printf("Variable is: %s\n", (char*)x);
}

int main(){
    char filename[10] = "file.txt";
    char *filePointer = filename;  //So it points to filename[0]'s address.
    uintptr_t x = (uintptr_t)filePointer;
    printSomeThing(x);
}

【讨论】:

    【解决方案2】:

    如果是sizeof(int) != sizeof(char*),那么一般来说,您尝试做的事情是不可能的。

    但是,仍有一种方法可以使这项工作正常进行。在我告诉你如何实现之前,让我重申一下其他人所说的:你不应该使用 int 作为指针。这不是一个好主意。我要演示的只是:演示。能做不代表就应该做。

    完成这项工作的一种方法是将内存映射到小于1 &lt;&lt; (sizeof(int) * 8) 的地址。然后,将您想要的字符串复制到该内存位置。现在,您可以将此指针传递给您的 printSomething(int) 函数。

    此解决方案存在一个问题:它不可移植,因此并不总是有效。我无法让它在 macOS 上与 clang 一起使用,但它确实可以工作 here。这是我使用的代码。

    #include <stdio.h>
    #include <sys/mman.h>
    #include <string.h>
    
    void printSomething(int x){
        printf("Variable is: %s\n", (char*) x);
    }
    
    int main(){
        char filename[10] = "file.txt";
        char *allocd = mmap((void*) 0x10000, sizeof(filename)+1,
                            PROT_READ | PROT_WRITE,
                            MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
        strcpy(allocd, filename);
        printSomething((int) allocd);
    }
    
    

    另一种可能仅用作演示的解决方案是您要求 gcc 在低内存地址处定义一个节。 This answer 做了一些类似的事情。这可能也不便携。

    【讨论】:

      【解决方案3】:

      考虑到您不想只传递指向数组的指针,我能想到的最佳方法是将其强制转换为无符号长整数以便将其提供给函数。

      但是您的编译器可能会抱怨您将整数值传递给 printf 中的字符串模式,但这是由于您使用的设计。

      如果您不需要使用printSomeThing(int i),则只需传递 char* 本身或使用 void* 如果您需要传递其他内容并使用某种标志来告诉函数您传递的类型

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-26
        • 2020-12-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-06-11
        • 1970-01-01
        相关资源
        最近更新 更多