为啥这个程序在调用函数时会出现分段错误?

Posted

技术标签:

【中文标题】为啥这个程序在调用函数时会出现分段错误?【英文标题】:Why this program gives a Segmentation Fault while calling a function?为什么这个程序在调用函数时会出现分段错误? 【发布时间】:2013-08-20 21:13:41 【问题描述】:

这是我的程序的一部分,当我运行这个程序时,我遇到了分段错误。我已将其范围缩小到这一行:

checkBase(ptr1, ptr2)

我将这两个都作为指针传递。并且它们被声明为 char* 并且它是运行时错误而不是编译时。 文件包含

http://www.google.com">www.spam.google.com

在这种情况下 ptr1 = www.google.com 和 ptr2 = spam.google.com

while(inf)

    count++;
    getline(inf, line);
    //cout << "*******" << count << "*******" << endl <<line << endl;
    p = new char[line.length()+1];
    strcpy(p, line.c_str());
    if(strstr(p, "href"))

        ptr = strstr(p, "href");
        while(ptr[0]!='\0')
            ptr += 1;
            if(ptr[0] == 'w' && ptr[1] == 'w' && ptr[2] == 'w')
                cout << ptr << endl;            
                ptr = strtok(ptr, "\"");
                cout << "add1   " << ptr << endl;
                add1 = ptr;
                ptr1 = ptr;
                ptr = strtok(NULL, "> ");
                add2 = ptr;
                ptr2 = ptr;
                cout << "ptr1: " << ptr1 << endl << "ptr2: " <<ptr2 << endl;
                if(add1 == add2)
                    cout << "There is an exact match at line: " << count << endl << line << endl;
                else
                    cout << "in else" << endl;
                    checkBase(ptr1, ptr2); //THIS GIVES A SEGMENTATION FAULT
                
            
        
    


void checkBase(char *add1, char *add2)
    cout << "here" << endl;
    char *base1[1000000], *base2[1000000];
    int count1 = 0, count2 = 0;
    base1[count1] = strtok(add1, ".");
    while(base1[count1] != NULL)
        count1++;
        base1[count1] = strtok(NULL, ".");
        cout << base1[count1] << endl;
    
    base2[count2] = strtok(add2, ".");
    while(base2[count2] != NULL)
        count2++;
        base2[count2] = strtok(NULL, ".");
    
    cout << base2[count2-1] << endl;
    if(((strcmp(base1[count1-1],base2[count2-1])) != 0) && (strcmp(base1[count1-2], base2[count2-2]) != 0))
        //if((strcmp(base1[count1-1], base2[count2-1]) != 0))
        cout << "Bases do not match: " << endl
             << base1[count1-2] << "." << base1[count1-1] << " and "
             << base2[count2-2] << "." << base2[count2-1] << endl;
        //
    
    else
        cout << "Bases match: " << endl
             << base1[count1-2] << "." << base1[count1-1] << " and "
             << base2[count2-2] << "." << base2[count2-1] << endl;          
    

我不知道为什么会出现分段错误。

【问题讨论】:

在调试器的监视下运行它,我敢打赌你会很快发现。你发现的那一行代码是你的错吗?是的,这就是不在这里的代码。 请为您的checkBase 函数添加代码。许多段错误是由使用未正确初始化为有效内存的指针引起的。我只能推测这是问题所在,直到我看到您的 checkBase 函数代码。 添加您实际声明变量的代码部分 还要检查 ptr1 和 ptr2 是否为空... 【参考方案1】:
char *base1[1000000], *base2[1000000];

毫无疑问,这会导致堆栈溢出。堆栈的大小是有限的,创建大小超过几 kb 的数组是个坏主意。尝试在堆上分配它们,例如vector&lt;char *&gt; base1(1000000)

您还应该计算所需的确切大小并分配那么多,或者在向量上 push_back。

【讨论】:

【参考方案2】:

除了@Neil Kirkwell 已经提到的堆栈溢出之外,还有几个问题

    那些不应该是仅以 base1[count1] 为条件的 while 循环!= NULL;您还应该确保 count1 小于数组中的元素数。 如果 count2 或 count1 为 0 或 1,您将尝试引用 -1 和 -2 的索引...不太好。 使用 strrchr 向后搜索,让您的生活更轻松 完全构建这些数组很浪费,因为您似乎只关心最后两个标记,每个标记只需要两个指针。

char *one_a = NULL, *one_b = NULL, *two_a=NULL, *two_b = NULL;
char *temp = strtok(add1, ".");
while (temp) 
    one_b = one_a;
    one_a = temp
    temp = strtok(NULL, ".");

char *temp = strtok(add2, ".");
while (temp) 
    two_b = two_a;
    two_a = temp
    temp = strtok(NULL, ".");

//now just compare one_a with two_a and one_b with two_b and you're done.

【讨论】:

以上是关于为啥这个程序在调用函数时会出现分段错误?的主要内容,如果未能解决你的问题,请参考以下文章

为啥在尝试调用采用动态参数的基本构造函数/方法时会出现此编译错误?

为啥调用firebase函数时会出现FCM错误

为啥我在函数内部调用时会收到“错误:无效的挂钩调用”?

默认构造函数的分段错误

分段错误将指针传递给函数

为啥调用函数时会有开销?