【问题标题】:Casting int function to void*将 int 函数转换为 void*
【发布时间】:2016-04-22 11:58:09
【问题描述】:

我在将返回的整数值转换为 void 指针时遇到问题。尝试了该站点的一些选项,但我的问题似乎仍未解决。尽管程序编译时没有代码错误,但我遇到了分段错误。我是不是瞎了,我的代码有错误吗?

#include<pthread.h>
#include<stdio.h>
#include<stdint.h>

int ackermann(int a, int b)
{
    if(a==0)
        return a+1;
    else if(a>0 && b==0)
    {
        return ackermann(a-1, 1);
    }
    else if(a>0 && b>0)
    {
        return ackermann(a-1,ackermann(a,(b-1)));
    }
}

int main(int argc, char* argv[])
{
    int a = atoi(argv[1]);
    int b = atoi(argv[2]);
    int c = ackermann(a,b);
    void *ptr = &c;
    pthread_t mythread;
    if(pthread_create(&mythread, NULL, ptr, NULL))
    {
        printf("Could not create a thread\n");
    }

    pthread_exit(NULL);
    return 0;
}

【问题讨论】:

  • 对我来说很好:ideone.com/AMD4k0
  • 提示:为什么要浪费argc
  • pthread_create 的第三个参数是指向函数的指针(在本例中为 ackerman),但您传递的是指向 int 的指针
  • 你想用pthread_create调用哪个函数?
  • Alter Mann 是对的:int c = ackermann(a,b); 行启动函数,计算结果并将其存储在整数中。当您执行 pthread_create ptr 指向整数 c 时 - 您正在尝试在主线程中启动整数,而不是函数,并且计算早已结束。

标签: c linux void-pointers


【解决方案1】:

正如 cmets 中提到的,您实际上并没有在单独的线程中调用函数 ackermann。您正在做的是直接从main 调用该函数,将结果存储在int 中,并将指向int 的指针作为第三个参数传递给pthread_create,它应该是指向要运行的函数。

目前,ackermann 没有合适的签名传递给pthread_create。启动新线程的函数应该这样声明:

void *my_thread_function(void *parameter);

鉴于ackermann 是递归调用的,将包装函数传递给pthread_create 并让该包装调用ackermann 而不是修改ackermann 以匹配上述签名会更简洁。

因为您需要将多个参数传递给线程函数,所以您需要创建一个包含所有参数的struct,并将指向该struct 的指针传递给线程函数。

您还可以将返回值存储在此结构中,以便启动线程的函数可以访问它。

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

int ackermann(int a, int b)
{
    if(a==0) {
        return a+1;
    } else if(a>0 && b==0) {
        return ackermann(a-1, 1);
    } else if(a>0 && b>0) {
        return ackermann(a-1,ackermann(a,(b-1)));
    }
    // if none of the above conditions are true, no value is returned
    // better check for this
}

struct ackermann_params {
    int a;
    int b;
    int result;
};

void *ackermann_thr(void *arg)
{
    struct ackermann_params *params = arg;
    params->result = ackermann(params->a, params->b);
    return NULL;
}

int main(int argc, char* argv[])
{
    struct ackermann_params params;
    if (argc < 3) {
        printf("invalid number of arguments\n");
        exit(1);
    }
    params.a = atoi(argv[1]);
    params.b = atoi(argv[2]);
    pthread_t mythread;
    if(pthread_create(&mythread, NULL, ackermann_thr, &params))
    {
        perror("Could not create a thread\n");
        exit(1);
    }
    if (pthread_join(mythread, NULL)) {
        perror("join failed\n");
        exit(1);
    }
    printf("result=%d\n", params.result);

    return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-03
    • 2019-11-19
    • 2013-11-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多