首页 > 解决方案 > 为什么函数调用发生在不同的输入和段错误中?

问题描述

这是我查找 1 和 n 之间最长的 collat​​z 序列的代码。显然对于 t 测试用例。在这里,我还使用了 memoization 并因此分配了“v”。但是随着函数cycles(int x)的输入超过4254,即。4255,发生了一些奇怪的事情。该函数正在输入一个数字 6053452 而不是 4255。因此,程序段错误,因为我们只为 5000000 个整数分配了空间。我做错了什么?

注意:程序运行愉快,直到 n = 4254!(不是阶乘)

#include <iostream>
#include <cstdlib>

    #define RANGE 5000000
    using namespace std;

    int *v = (int*)malloc(sizeof(int)*RANGE);

    int cycles(int x){
        int c = 1;
        
        
        while(x!=1){
            
            if(v[x]!=0){
                c = c + v[x];
                break;
            }
            
            if(x%2){
                x = 3*x + 1;
            }else{
                x/=2;
            }
            c++;
        }
        
        v[x] = c;
        
        return c;
        
    }


    void solve(int n){
        
        int mx = 0;
        int mx_cnt = 0;
        int c;
        
        for(int i=1;i<=n;i++){
            c = cycles(i);
            if(c >= mx_cnt){
                mx = i;
                mx_cnt = c;
            }
            
        }
        
        cout << mx << endl;
        
    }

    int main(){
        
        
        int t,n;

        cin >> t;

        while(t--){

            cin >> n;

            solve(n);


        }
        

        
        return 0;
    }

标签: c++memorysegmentation-fault

解决方案


v指向一个malloced 数组并且malloc不进行初始化。你有一个未初始化的变量if(v[x]!=0)c = c + v[x];对其进行操作。拥抱 C++ 并将malloced 数组替换为std::vector. vector初始化其内容。

这可能不是唯一的错误,只是最明显的错误。

根据 molbdnilo 在评论中提出的观点进行更正:我使用了过于复杂的工具。int v[RANGE];将分配数组并将其初始化为零。由于数组永远不会改变大小,因此 avector的动态数组是不必要的。使用std::array<int, RANGE> v;,您将拥有一个零初始化的固定大小数组,并且仍然可以获得有用的功能,例如at用于调试。


推荐阅读