【问题标题】:Some issue concerning fprint and pointers关于 fprint 和指针的一些问题
【发布时间】:2015-09-08 15:54:59
【问题描述】:

我正在学习操作系统课程,我对以下代码有一些疑问

#include <stdio.h>
int * addition(int a, int b){
    int c = a + b;
    int *d = &c;
    return d;
}
int main(void){
    int result = *(addition(1,2));
    int *result_ptr = addition(1,2);
    /*never interchange */
    printf("result = %d\n", *result_ptr);
    printf("result = %d\n", result);
    return 0;
}
//this code outputs 3
                    3

这是我交换 printfs 时发生的情况,实际上第二个只是打印出一个随机地址

#include <stdio.h>
int * addition(int a, int b){
    int c = a + b;
    int *d = &c;
    return d;
}
int main(void){
    int result = *(addition(1,2));
    int *result_ptr = addition(1,2);
    /*never interchange */
    printf("result = %d\n", result);
    printf("result = %d\n", *result_ptr);
    return 0;
}
//this code outputs 3
                    and a random address

但是,如果我把它们做成一个 printf

#include <stdio.h>
int * addition(int a, int b){
    int c = a + b;
    int *d = &c;
    return d;
}
int main(void){
    int result = *(addition(1,2));
    int *result_ptr = addition(1,2);
    /*never interchange */
    printf("result = %d %d \n", result, *result_ptr);
    return 0;
}
//this code outputs 3 3

不知道printf是不是清空了内存,所以指针变危险了?

【问题讨论】:

  • 在'addition()'函数中,返回的指针指向栈上的一个变量。当函数退出时,该堆栈变量“超出范围”(因此不再有效并表现出可能导致段错误事件的未定义行为
  • 此声明:int result = *(addition(1,2)); 有效。这个声明:int *result_ptr = addition(1,2); 现在有一个指向堆栈上“某处”的指针。某处不再有效(即取消引用该指针的未定义行为。
  • 'printf()' 破坏了变量所在的堆栈,因为它实现了自己的堆栈值。

标签: c pointers operating-system printf


【解决方案1】:

问题出在您的addition 函数中。您正在返回一个局部变量的地址。因为局部变量存在于堆栈中,所以当函数返回时,该变量的内存超出范围。这会导致未定义的行为,例如您所经历的。

要使其正常工作,您需要使用malloc 在堆上分配内存:

int *addition(int a, int b){
    int *d = malloc(sizeof(int));
    *d = a + b;
    return d;
}

当此函数返回时,您需要确保free 完成后返回的指针。否则会出现内存泄漏。

【讨论】:

  • 非常感谢!事实上,我的教授写了加法函数,并要求我们解释前两段代码的结果
  • 很高兴我能帮上忙。如果您觉得有用,请随时 accept this answer
  • 但是我不明白为什么第一段代码打印出两个3s
  • @ergutebao 未定义的行为(UB)意味着任何事情都可能是结果。它可能第一次工作,但当您进行一些小的更改时会失败。阅读更多关于 UB 以了解更多信息。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-12-09
  • 2020-08-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多