【问题标题】:Segmentation fault while using function pointer使用函数指针时出现分段错误
【发布时间】:2015-03-24 06:05:35
【问题描述】:

在 main() 之前声明函数指针时出现分段错误 并为其分配 main 中函数的地址。如果函数指针在 main() 之前声明,实际会出现什么问题?

代码如下:

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

void fun1(char *str)
{
    printf("%s",str);
}

void (* funptr)(char *);

int main()
{

    char msg1[10]="Hi";
    char msg2[10]="Hello";
    pthread_t pid1, pid2;

    funptr=&fun1;

    pthread_create(&pid1,NULL,(void *)(*funptr),(void *)msg1);
    pthread_create(&pid1,NULL,(void *)(*funptr),(void *)msg2);

    pthread_join(pid1,NULL);
    pthread_join(pid2,NULL);
    return 0;
}

而当我在 main() 中声明 funptr 时,它会给我正确的输出。想知道到底是什么问题。

问题出在线程 ID 上。我对两个线程都使用了相同的线程 ID“pid1”,并且我试图加入“pid2”,这也导致了分段错误。以下是修正后的代码...

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

void fun1(char *str)
{
    printf("%s",str);
}

 void (* funptr)(char *);

int main()
{

    char msg1[10]="Hi";
    char msg2[10]="Hello";
    pthread_t pid1, pid2;

    funptr=&fun1;

    pthread_create(&pid1,NULL,(void *)(*funptr),(void *)msg1);
    pthread_create(&pid2,NULL,(void *)(*funptr),(void *)msg2);
    pthread_join(pid1,NULL);
    pthread_join(pid2,NULL);
    return 0;
}

【问题讨论】:

  • pthread_create 具有相同的 pid,因此崩溃。
  • 不管怎样,函数和指针都是错误的。它们应该匹配void* (*)(void*)。停止强制转换并正确声明您的函数和指针。

标签: c segmentation-fault function-pointers


【解决方案1】:

funptr 已经是一个函数指针。要将其转换为void *,您只需要(void *)funptr。您需要有void *(*) (void *) 类型的第三个参数,而不是将您的函数转换为void*。见pthread_create documentation

正如 Santhosh 在 cmets 中所写,SIGSEGV 的原因是 pthread_create() 作为指向同一 pthread_t 的参数指针给出。

【讨论】:

  • “但你不需要将你的函数强制转换为 void*” - 他正在强制转换为 void* 以规避其他类型检查的编译失败,因为 void (*funptr)(char*) 不匹配 pthread_create、void * (*)(void*) 所需的>正确函数类型。应该更正函数和指针,并删除 所有 不需要的强制转换,like this
  • 是的,函数的类型应该是void *(*) (void *)。但是msg1msg2 必须强制转换为void *
  • 不,他们没有。我之前评论中的链接代码将在任何支持 pthread 的平台上使用标准 C 编译器按原样编译。
  • @WhozCraig 见pthread_create() man page。最后一个参数的类型应该是void*,而不是char*
  • 我知道phread_create 的要求。不需要强制转换,因为它们已经隐式强制转换为void*(与其他所有数据指针类型一样)。
【解决方案2】:
pthread_create(&pid1,NULL,(void *)(*funptr),(void *)msg1);
pthread_create(&pid1,NULL,(void *)(*funptr),(void *)msg2);

在两个线程创建中,您都在使用 pid1。

pthread_join(pid2,NULL); pid2 只不过是一个垃圾值......

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-18
    • 2020-12-27
    • 2020-10-04
    • 2022-11-16
    相关资源
    最近更新 更多