【问题标题】:Returning pointer from a function从函数返回指针
【发布时间】:2011-12-06 23:40:36
【问题描述】:

我正在尝试从函数返回指针。但是我遇到了分段错误。有人请告诉代码有什么问题

#include<stdio.h>
int *fun();
main()
{
    int *ptr;
    ptr=fun();
    printf("%d",*ptr);

}
int *fun()
{
    int *point;
    *point=12;  
    return point;
}   

【问题讨论】:

  • 处理指针时最重要的问题是:指向什么的指针? 一个本地对象?卡布姆。动态分配的对象?被谁释放?一些对象存储在其他地方?那么该对象能存活多久,我的指针有效多久?从函数返回指针尤其充满风险,因为指针是在完全不同的代码中初始化的(调用者通常甚至看不到),而调用者不知道如何处理结果。此类功能的良好文档非常重要。
  • 请记住始终 malloc 任何对象、指针和数据结构。如果你不这样做,你总是会遇到分段错误,因为它只是说我们没有为你分配任何空间。
  • 当您“更改代码中的错误”时,您的答案(部分)与问题无关。有问题的代码并不完美,这就是问题的原因。我强烈建议避免修复任何有问题的代码。
  • 您好,通过malloc 进行操作和像*ptr = 12 进行操作有什么区别?为什么前者即使在发送方本地声明时也会返回指向调用方的有效指针,而后者却没有?
  • @AttitudeMonger 因为malloc 说“我想要一些内存来存储东西”,但普通的旧*ptr = 12 说“我想要一些内存来进行计算,它可以用于其他以后的事情”。

标签: c pointers segmentation-fault


【解决方案1】:

在使用指针之前分配内存。如果你不分配内存*point = 12 是未定义的行为。

int *fun()
{
    int *point = malloc(sizeof *point); /* Mandatory. */
    *point=12;  
    return point;
}

你的printf 也是错误的。您需要取消引用 (*) 指针。

printf("%d", *ptr);
             ^

【讨论】:

  • 如果要存储多个值,我会怎么做?是需要全部分配还是只增加指针?
  • @user567879 您需要malloc 更多空间。类似int *point = malloc(num_values * sizeof *point);
  • int *point = calloc(num_values,sizeof(int)) 也很有用。更多信息thinkage.ca/english/gcos/expl/c/lib/calloc.html
  • 从函数返回指针并让主程序释放内存是一种好习惯吗?还有什么其他的选择吗? (仅在这不是一个好习惯的情况下)
  • @cnicutar: 最好将 malloc 的结果转换为 int*,尽管在 C 中没有必要,
【解决方案2】:

虽然返回一个指向本地对象的指针是不好的做法,但它并没有在这里引起轰动。这就是您遇到段错误的原因:

int *fun()
{
    int *point;
    *point=12;  <<<<<<  your program crashed here.
    return point;
}

本地指针超出范围,但真正的问题是取消引用从未初始化的指针。点的价值是多少?谁知道。如果该值未映射到有效的内存位置,您将获得 SEGFAULT。如果幸运的是它映射到了有效的东西,那么您只是通过将分配给 12 的内容覆盖该位置而破坏了内存。

由于返回的指针立即被使用,在这种情况下,您可以返回本地指针。但是,这是不好的做法,因为如果在另一个函数调用重用堆栈中的内存之后重用该指针,则程序的行为将是未定义的。

int *fun()
{
    int point;
    point = 12;
    return (&point);
}

或几乎相同:

int *fun()
{
    int point;
    int *point_ptr;
    point_ptr = &point;
    *point_ptr = 12;
    return (point_ptr);
}

另一种不好但更安全的方法是将整数值声明为静态变量,这样它就不会在堆栈上,并且不会被另一个函数使用:

int *fun()
{
    static int point;
    int *point_ptr;
    point_ptr = &point;
    *point_ptr = 12;
    return (point_ptr);
}

int *fun()
{
    static int point;
    point = 12;
    return (&point);
}

正如其他人所提到的,“正确”的做法是通过 malloc 在堆上分配内存。

【讨论】:

  • free()使用后。
  • 使用static会导致编译警告吗?
【解决方案3】:

在将值 12 分配给整数指针时,它没有分配内存。因此它崩溃了,因为它没有找到任何内存。

你可以试试这个:

#include<stdio.h>
#include<stdlib.h>
int *fun();

int main()
{
    int *ptr;
    ptr=fun();
    printf("\n\t\t%d\n",*ptr);
}

int *fun()
{
    int ptr;
    ptr=12;
    return(&ptr);
}

【讨论】:

  • 不是 12 只存在于那个函数调用的栈上吗?这似乎会产生未定义的行为
【解决方案4】:

据我所知,关键字 new 的使用与 malloc(sizeof identifier) 的作用相对相同。下面的代码演示了如何使用关键字 new。

    void main(void){
        int* test;
        test = tester();
        printf("%d",*test);
        system("pause");
    return;
}
    int* tester(void){
        int *retMe;
        retMe = new int;//<----Here retMe is getting malloc for integer type
        *retMe = 12;<---- Initializes retMe... Note * dereferences retMe 
    return retMe;
}

【讨论】:

  • 从未在C 中开发过,但new 不是C++
  • 没错;但是,我发现 new 和 delete 实际上在 C 中与内存管理一起使用。
  • 这根本不正确。 C 没有关键字newdelete
猜你喜欢
  • 2010-12-25
  • 2011-07-19
  • 1970-01-01
  • 2019-08-22
  • 2015-07-18
  • 2016-10-23
  • 2018-12-13
  • 2013-04-10
  • 1970-01-01
相关资源
最近更新 更多