【问题标题】:Returning result via pointer to array通过指向数组的指针返回结果
【发布时间】:2021-12-23 03:19:11
【问题描述】:

我想通过作为参数给出的指针*address 返回函数的结果。我下面的代码打印了这个输出:

Result:

但我期待:

Result: 123456

为什么没有按预期工作?

#include <stdio.h>

static void get_address(char *address) {
    address = "123456";
}


int main(int argc, const char * argv[]) {

    char address[34];
    get_address(address);
    printf("Result: %s\n",address);

    return 0;
}

【问题讨论】:

  • address in get_address 是指向 main 中 address 的本地指针。更改指针对 main 没有影响。
  • 在 C 中,所有参数都是 按值传递。这意味着当您调用函数时,参数值会复制到函数的局部参数变量中。以任何方式修改此副本(例如分配给它)都不会更改原始值。
  • 我很确定这是重复的。简而言之,get_address 在指针的副本 中传递main 中的34 个字符数组的地址。它更改副本,使其指向字符“123456”的常量数组,但main 中的同名变量不会更改。将传递给get_address() 的参数与main() 中的局部变量同名并没有帮助
  • 你可能想要这个:static void get_address(char* address) { strcpy(address, "123456"); } 。并且不要忘记`#include
  • 此外,您的前提是错误的,您实际上是尝试分配给一个数组,这是不可能的。您只能复制 到数组。从这里应该很容易弄清楚如何解决您的问题:您需要将字符串复制到address。与例如strcpy.

标签: c function pointers


【解决方案1】:
get_address 中的

'address' 获取 main() 中数组address 的起始地址的副本。 get_address 将本地指针更改为本地字符串“123456”的地址,然后什么也不做。 你的意思大概是这样的:

#define DEST_BUFFER_SIZE  34
static void get_address(char* address) {
    const char str[] = "123456";
    strcpy_s(address, DEST_BUFFER_SIZE, str);
}

int main(int argc, const char * argv[]) {
    char address[DEST_BUFFER_SIZE];
    get_address(address);
    printf("Result: %s\n", address);
    return 0;
}

这里strcpy_sstrcpy的安全版本,用于将本地str字符数组的内容复制到addressget_address中指定的内存位置。

【讨论】:

  • 使用source的长度来限制复制是不安全的。 strcpy_s() 无论如何都会受到 str 长度的限制。应该给它 target 空间的大小,编写的函数不知道。如果原始字符串是char address[4];,它将失败。
  • @WeatherVane 感谢您的反馈。回想一下 strcpy_s 需要字符串长度 (en.cppreference.com/w/c/string/byte/strcpy)。我已经编译并测试了这个,这个版本给出了想要的输出(在 VS2019 中)。在当前示例的上下文中,这是可以的,因为address 有足够的空间并且要复制的字符串小于容量。如果我们笼统地谈论,我们将不得不添加额外的机制来确保安全。
  • 不,它需要目的地的大小。 strcpy 的危险在于源字符串超出目标缓冲区(无论源字符串是否为 nul 终止)。 strcpy_s 的参数在您的链接中被 MS 命名为 dest_sizedestsz。我建议你尝试使用一个太小的缓冲区,例如char address[4];,看看它是否仍然安全。使用源字符串的长度作为 sa 保护是没有意义的,因为 strcpy_s 无论如何都会停在那里。
  • 只要输入参数的长度小于缓冲区容量就可以了。正如我在之前的评论中所说,在所述问题的背景下,这没有任何问题。在问题中,缓冲区长度足够大,并且在我的代码中正确给出了源字符串的长度(包括空终止符)。再次 - 正如我在对您的第一条评论的回答中所说 - 缓冲区长度不足的情况是一般情况,并且在问题中没有关于这种一般情况的明确声明。感谢您的关心。
  • @WeatherVane 好的,我想我们一直在从不同的角度看待这个问题。您可能想指出 strcpy_s 的正确用法。我已经按照您的建议编辑了代码并检查了它,它可以工作。谢谢!
【解决方案2】:
#include <stdio.h>

static void get_address(char *address) {
     //Attention here
     // use the reference operator
     // (in your code you were affecting to the address of the variable not it's content)
    *address = "123456";
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多