【问题标题】:Segmentation fault while returning pointer返回指针时出现分段错误
【发布时间】:2016-05-17 06:30:29
【问题描述】:

我已经开始学习 C 语言中的指针了。

当我尝试在函数中返回指针时,我收到segmentation fault 错误。

代码如下:

#include<stdio.h>

int *sum(int *, int *);

int main(void)
{
    int a, b;
    int *ans = NULL;
    printf("Enter number a : ");
    scanf("%d", &a);
    printf("Enter number b : ");
    scanf("%d", &b);

    ans = sum(&a, &b);
    printf("Sum = %d", *ans); 

    return 0;   
}

int *sum(int *p, int *q)
{
    int *result = NULL;
    *result = *p + *q;
    return (result);
}

然后输出:

Enter number a : 10
Enter number b : 20
Segmentation fault

result 被声明为指针时,sum 函数中发生分段错误。但是,我无法弄清楚同样的原因。任何有关这方面的帮助都是非常可观的。

【问题讨论】:

  • 取消引用空指针是不合法的。

标签: c pointers segmentation-fault


【解决方案1】:

你正在初始化一个指向 NULL 的指针,然后你正在推迟它:它是 Undefined behavior

sum函数改为

int *sum(int *p, int *q)
{
    int *result = malloc(sizeof(int));

    // check if malloc returned a valid pointer before to dereference it
    if (result != NULL)
    {
        *result = *p + *q;
    }

    return (result);
}

并添加一个free 调用以释放分配的内存。

    // check if sum function allocate the pointer before to dereference it
    if (ans != NULL)
    {
       printf("Sum = %d", *ans); 
    }

    free(ans);

    return 0;   
}

你也可以避免使用指针返回值:

#include<stdio.h>

int sum(int *, int *);

int main(void)
{
    int a, b;
    int ans;
    printf("Enter number a : ");
    scanf("%d", &a);
    printf("Enter number b : ");
    scanf("%d", &b);

    ans = sum(&a, &b);
    printf("Sum = %d\n", ans); 

    return 0;   
}

int sum(int *p, int *q)
{
    int result = *p + *q;
    return (result);
}

sum 函数也可以是:

int sum (int *p, int *q)
{
    return (*p + *q);
}

编辑

正如@JonathanLeffler 在他的回答中所写,您也可以这样做:

#include<stdio.h>

void sum(int *, int *, int *);

int main(void)
{
    int a, b;
    int ans;
    printf("Enter number a : ");
    scanf("%d", &a);
    printf("Enter number b : ");
    scanf("%d", &b);

    sum(&ans, &a, &b);
    printf("Sum = %d\n", ans);

    return 0;
}

void sum(int *result, int *p, int *q)
{
    *result = *p + *q;
}

【讨论】:

  • 将参数作为指针传递确实没有任何好处,因此如果您愿意,可以使用static inline int sum(int p, int q) { return p + q; },尽管您可能希望将其放在使用它的上方。
  • @JonathanLeffler 是的,当然,但是 OP 写道:我已经开始学习 C 中的指针
  • 关于指针的其中一个教训是何时使用指针,何时不使用指针。
  • 谢谢!这真的很有帮助。使用 malloc 解决了这个问题。我确实想出了替代方案,但是我想专门实现 返回指针的函数。感谢您的帮助!
【解决方案2】:

在尝试存储任何东西之前分配内存,并检查malloc()的返回

int *result = NULL;
result = malloc(sizeof(*result));
if(result != NULL)
    *result = *p + *q;
else
    printf("malloc returned error");

另外,检查main()中函数的返回并相应地退出。

int main(void)
{
    .
    .
    .
    ans = sum(&a, &b);
    if(ans == NULL)
        return 0;

    printf("Sum = %d\n", ans);
    free(ans);    //free the memory then
    return 0;
}

【讨论】:

  • 为什么不:int *result = malloc(sizeof(*result));?使用if (result != NULL) *result = *p + *q; 可能是个好主意。也没有充分的理由通过指针而不是值来传递参数。
  • @JonathanLeffler。谢谢。添加了返回值检查。
  • @M.M,现在一切就绪。 :)
【解决方案3】:

第三种选择是在main 函数中将ans 声明为普通的int 变量,并将指向它的指针传递给sum 函数,就像您对其他两个参数所做的那样。这实际上是在模拟 按引用调用

【讨论】:

  • 我冒昧地根据您的回答在我的回答中添加代码。
【解决方案4】:

#include<stdio.h>

int *sum(int *, int *);

int main(void)
{
    int a, b;
    printf("Enter number a : ");
    scanf("%d", &a);
    printf("Enter number b : ");
    scanf("%d", &b);

    int* ans = sum(&a, &b);
    printf("Sum = %d", *ans); 

    return 0;   
}

int *sum(int *p, int *q)
{
    int plus = *p + *q;
    int *ans = &plus;
    return ans;
}
将 Sum 存储在不同的变量 plus 中,并创建一个指向该变量 plus 的指针 *ans 并返回包含 plus 地址的指针变量 ans

【讨论】:

    猜你喜欢
    • 2021-12-22
    • 1970-01-01
    • 2020-02-09
    • 1970-01-01
    • 1970-01-01
    • 2023-03-17
    • 2020-02-18
    • 1970-01-01
    相关资源
    最近更新 更多