来自atoi的Segfault

时间:2015-01-29 07:58:26

标签: c multithreading pointers

我刚开始编写线程代码并且生锈了C.我已经尝试使用gdb进行调试了,看起来我尝试使用atoi设置num的值后得到了段错误,但我是不知道为什么。任何人都可以解释这个段错误吗?

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

int *ptr;

int getFibonacciNumber(int num)
{
    if ( num <= 1 ) return num;
    else if ( ptr[num] != 0 ) return ptr[num];
    else{
        int fibOfNMO = getFibonacciNumber(num - 1);
        int fibOfNMT = getFibonacciNumber(num - 2);
        ptr[num] = fibOfNMO + fibOfNMT;
        return ptr[num];
    }
}

void* fibonacci(void* arg)
{
    int* num = (int*)arg;
    int fib = getFibonacciNumber(*(num));

    return NULL;
}

int main(int argc, char** argv)
{
    printf("%s", argv[0]);
    pthread_t tid_main;
    pthread_t tid_fib;
    int ret;
    int* num;
    *num = atoi(argv[0]);

    if ( argv[0] != NULL ) ptr = (int*)malloc((*(num) + 1)*sizeof(int));
    else exit(EXIT_FAILURE);

    int i;
    for (i = 0; i < *(num) + 1; ++i) ptr[i] = 0;
    ptr[1] = 1;

    printf("%d\n", getFibonacciNumber(6));
    ret = pthread_create(&tid_fib, NULL, fibonacci, num);
    if (ret) {
        fprintf(stderr, "error -- pthread_create() failed.\n");
            exit(EXIT_FAILURE);
        }

    ret = pthread_join(tid_fib, NULL);
    if (ret) {
            fprintf(stderr, "error -- pthread_join() failed.\n");
            exit(EXIT_FAILURE);
        }

    printf("%d\n", ptr[*(num)]);
    free(ptr);
    return 0;
}

4 个答案:

答案 0 :(得分:3)

int* num;
*num = atoi(argv[0]);

取消引用未初始化的指针 - 未定义的行为。

将其更改为

int num;
num = atoi(argv[0]);

int *num = malloc(sizeof(int));
*num = atoi(argv[0]);

答案 1 :(得分:1)

Num是一个指针,指向任何东西。

中纠正它
int main(int argc, char** argv)
{
    printf("%s", argv[0]);
    pthread_t tid_main;
    pthread_t tid_fib;
    int ret;
    int num;
    num = atoi(argv[0]);

请注意,这意味着整个主要功能代码必须将num视为int而不是int *

答案 2 :(得分:0)

你得到一个段错误,因为num没有被初始化为指向任何东西(或者更确切地说,编译器可能使它成为空指针)。然后尝试为此垃圾指针分配一个变量。

你必须malloc使用一些内存,或者只是将它声明为一个静态变量,并在必要时使用一元&创建一个指向它的指针。

答案 3 :(得分:0)

int* num;
*num = atoi(argv[0]);
  1. num是一个指针,它应该在向它写入内容之前指向一些有效的内存位置。在你的情况下,你不这样做,所以你看到分段错误。

  2. 如果argc大于0,
  3. argv[0]将始终是程序的名称。

  4.   

    如果argc的值大于零,则数组成员argv [0]   通过argv [argc-1]包含指向字符串的指针,   由主机环境给出实现定义的值   在程序启动之前。目的是提供给该计划   在程序启动之前从其他地方确定的信息   托管环境。 [...]

         

    如果argc的值大于零,   argv [0]指向的字符串表示程序名称;   如果程序名不是,则argv [0] [0]应为空字符   可从主机环境获得。 [...]

    PS:atoi(NULL)导致崩溃,argv[0]可能为NULL。