返回指针时出现分段错误

时间:2016-05-17 06:30:30

标签: c pointers segmentation-fault

我已经开始在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

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

4 个答案:

答案 0 :(得分:4)

在尝试存储任何内容之前分配内存,并检查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;
}

答案 1 :(得分:4)

您正在启动指向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;
}

答案 2 :(得分:2)

第三种方法是将ans声明为int函数中的普通main变量,并将指针传递给sum函数,就像使用 [Authorize] public ActionResult Index(Int32? days) { string currentUser = this.User.Identity.GetUserName(); var orders = db.Orders //assume db is something inherited from DbContext .Where(o => o.UserName == currentUser) .OrderByDescending(o => o.OrderDate); if (days.HasValue) { var startingDate = DateTime.Now.AddDays((-1) * days.Value); orders = orders.Where(o => o.OrderDate >= startingDate); } var orderList = orders.ToList(); var returnOrderIds = db.ReturnDetails.Select(detail => detail.OrderId).ToList(); //here you will need to check with business analyst staff what is the rule for 'returnstats'. //The business logic here is that if there is at least one order whose OrderId is in the ReturnDetails //the 'returnstats' is 'Returning Item' otherwise it's 'Processing'. if (orderList.Any(o => returnOrderIds.Contains(o.OrderId)) { ViewBag.returnstats = "Returning Item"; } else { ViewBag.returnstats = "processing"; } var viewModels = ...//the source code to create Order ViewModel with variable orderList return View(viewModels); } 函数一样另外两个论点。这实际上是通过引用模拟调用

答案 3 :(得分:1)

#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 中并创建一个指向该变量 *ans 的指针 plus 并返回保存 {{1} 地址的指针变量 ans }