【问题标题】:Passed parameter changes value传递的参数改变值
【发布时间】:2013-03-22 21:08:02
【问题描述】:

代码如下:

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

void foo(int* ptr) {
    printf("ptr is %x\n", ptr);
}

void main() {
    int* ptr = (int*)malloc(sizeof(int));
    printf("ptr is %x\n", ptr);
    foo(ptr);
    free(ptr);
}

...他就是输出:

ptr is 0x007446c0
ptr is 0x00000000

...问题是:
为什么会发生在我身上???

【问题讨论】:

  • 冒着与其他人一样破纪录的风险,不要在 C 中强制转换 malloc() -- 使用 "int* ptr = malloc( sizeof( int ) );"
  • @Jacob Spire 看到这个:stackoverflow.com/questions/1565496/…
  • @JacobSpire 我在Visual C++ 2010 Express 上尝试了你的程序,我得到了正确的打印。你确定你得到的第二个数字是 0x0 吗?
  • @Ganesh - 由于可修改左值的答案,您看到的值可能会有所不同,传递错误的格式说明符是 UB。
  • @Mike.. 谢谢.. 为什么要使用 %x 格式说明符打印 0x0 而不是其他一些 junk 值?

标签: c visual-studio-2010 pointers memory parameters


【解决方案1】:

这是因为printf 中的%x 需要一个无符号整数,而不是指针。

以下是修复程序以获得所需行为的方法:

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

void foo(int* ptr) {
    printf("ptr is %p\n", (void*)ptr);
}

int main() {
    int* ptr = malloc(sizeof(int));
    printf("ptr is %p\n", (void*)ptr);
    foo(ptr);
    free(ptr);
    return 0;
}

这里是link to ideone;运行产生预期结果:

ptr is 0x8fa3008
ptr is 0x8fa3008

【讨论】:

  • 我用%x 尝试过原始程序,它运行良好,没有任何问题。我在gcc (MinGW)Visual C++ 2010 Express 上都试过了,在这两种环境下都成功了。为什么%x 应该打印 0x0 而不是一些垃圾号码?
  • @Ganesh 这就是未定义行为的危险:有时它会产生“正确的事情”。 %x 可以打印零的一个原因是 64 位地址:上半部分很可能为零。
【解决方案2】:

我猜是因为您的程序调用了未定义的行为。这就是我认为您的意思:

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

void foo(int* ptr) {
    printf("ptr is %p\n", (void *) ptr); /* %x tells printf to expect an unsigned int. ptr is not an unsigned int. %p tells printf to expect a void *, which looks a little better, yeh? */
}

int main() { /* main ALWAYS returns int... ALWAYS! */
    int* ptr = malloc(sizeof(int)); /* There is no need to cast malloc. Stop using a C++ compiler to compile C. */
    printf("ptr is %p\n", (void *) ptr);
    foo(ptr);
    free(ptr);
}

这能解决你的问题吗?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多