进入 main 之前 C++ 中的分段错误
Segmentation fault in C++ before entering main
这是一个很常见的问题,我尝试阅读解决方案,但其中 none 似乎解决了我的问题。这是我写的代码,我知道它很乱,因为我是 C++ 的新手。
#include<iostream>
#include<string>
#include<iomanip>
#include<set>
#include<queue>
#include<cmath>
#include<algorithm>
#include<vector>
#include<limits.h>
#include<math.h>
#include<map>
#include<cstring>
using ll = long long;
const int N = 2e6+6;
int main(){
std::ios_base::sync_with_stdio(0);
std::cin.tie(0);
int n,m;
std::cin >> n >> m;
std::vector<std::array<int,3>> edges;
int exist[n][n];
memset(exist,0,sizeof(exist));
for(int i = 0; i < m;++i){
int a,b;
char c;
std::cin >> a >> b >> c;
--a,--b;
edges.push_back({a,b,c-'a'});
exist[a][b] = exist[b][a] = 1;
}
std::vector<int> adj[N];
std::map<std::pair<int,int>,int> nodes;
int node = 0;
for(int i = 0; i < m;++i){
for(int j = 0; j < m;++j){
if(i == j)
continue;
if(edges[i][2] != edges[j][2])
continue;
int a = edges[i][0];
int b = edges[i][1];
int c = edges[j][0];
int d = edges[j][1];
if(nodes[{a,c}] == 0)
nodes[{a,c}] = ++node;
if(nodes[{b,d}] == 0)
nodes[{b,d}] = ++node;
if(nodes[{a,d}] == 0)
nodes[{a,d}] = ++node;
if(nodes[{b,c}] == 0)
nodes[{b,c}] = ++node;
adj[nodes[{a,c}]].push_back(nodes[{b,d}]);
adj[nodes[{b,d}]].push_back(nodes[{a,c}]);
adj[nodes[{a,d}]].push_back(nodes[{b,c}]);
adj[nodes[{b,c}]].push_back(nodes[{a,d}]);
}
}
int start = nodes[{0,n-1}];
int ans = 1e9+7;
std::queue<int> q;
q.push(start);
std::vector<int> dist(node+1,-1);
dist[start] = 0;
std::vector<bool> visited(node+1,false);
visited[start] = true;
auto it = nodes.begin();
while(!q.empty()){
int cur_node = q.front();
q.pop();
for(int i = 0; i < (int)adj[cur_node].size();++i){
int next_node = adj[cur_node][i];
if(!visited[next_node]){
q.push(next_node);
visited[next_node] = true;
dist[next_node] = dist[cur_node] + 1;
}
}
}
for(int i = 0; i < n;++i){
for(int j = 0; j < n;++j){
int node = nodes[{i,j}];
if(node == 0)
continue;
if(dist[node] == -1)
continue;
if(i == j || (exist[i][j] == 1)){
ans = std::min(ans,dist[node]);
}
}
}
if(ans == 1e9+7)
ans = -1;
std::cout << ans << "\n";
}
这个程序甚至在进入 main 之前就给出了分段错误,我尝试使用 gdb,它也说错误在 int main()
行。我完全不明白发生了什么,我也尝试 运行 在 C++ 14 和 C++ 17 上运行程序,它 运行 很好,但我使用的是 C++ 11,它编译成功但没有't 运行。请帮助我。
您在堆栈中的代码中分配了超过 200 万 std::vector
s。通常堆栈不是很大,所以肯定会超过保留的 space 并导致问题。局部对象的分配发生在函数中的任何代码 运行 之前,因此看起来它在函数中崩溃但在您的任何代码 运行.
之前
std::vector<int> adj[N];
如果您需要那么多向量,则需要动态分配它。
首先,这不是有效的 C++:
int n;
cin >> n;
int exist[n][n]; // <-- not valid C++
C++ 中的数组的大小必须由编译时表达式表示,而不是运行时值。 C++ does not support variable-length arrays.
已编译的代码,因为有些编译器默认支持此功能。但它仍然不受 C++ 语言规范的支持。例如,Visual C++ 编译器不支持这种语法。如果您尝试使用 Visual C++ 编译代码,您会收到相应的错误消息。
即使支持,较大的 n
值也可能会破坏堆栈内存,因为堆栈内存是有限的。
那么第二个问题就是你有这个:
std::vector<int> adj[N];
如果N
很大,那就是N
std::vector<int>
的数组。同样,这很可能会耗尽堆栈内存。
一种解决方案是使用 std::vector<std::vector<int>>
:
std::vector<std::vector<int>> exist(n, std::vector<int>(n));
//...
std::vector<std::vector<int>> adj(N):
由于 vector 从堆中获取内存,因此堆栈内存耗尽问题消失了。
这是一个很常见的问题,我尝试阅读解决方案,但其中 none 似乎解决了我的问题。这是我写的代码,我知道它很乱,因为我是 C++ 的新手。
#include<iostream>
#include<string>
#include<iomanip>
#include<set>
#include<queue>
#include<cmath>
#include<algorithm>
#include<vector>
#include<limits.h>
#include<math.h>
#include<map>
#include<cstring>
using ll = long long;
const int N = 2e6+6;
int main(){
std::ios_base::sync_with_stdio(0);
std::cin.tie(0);
int n,m;
std::cin >> n >> m;
std::vector<std::array<int,3>> edges;
int exist[n][n];
memset(exist,0,sizeof(exist));
for(int i = 0; i < m;++i){
int a,b;
char c;
std::cin >> a >> b >> c;
--a,--b;
edges.push_back({a,b,c-'a'});
exist[a][b] = exist[b][a] = 1;
}
std::vector<int> adj[N];
std::map<std::pair<int,int>,int> nodes;
int node = 0;
for(int i = 0; i < m;++i){
for(int j = 0; j < m;++j){
if(i == j)
continue;
if(edges[i][2] != edges[j][2])
continue;
int a = edges[i][0];
int b = edges[i][1];
int c = edges[j][0];
int d = edges[j][1];
if(nodes[{a,c}] == 0)
nodes[{a,c}] = ++node;
if(nodes[{b,d}] == 0)
nodes[{b,d}] = ++node;
if(nodes[{a,d}] == 0)
nodes[{a,d}] = ++node;
if(nodes[{b,c}] == 0)
nodes[{b,c}] = ++node;
adj[nodes[{a,c}]].push_back(nodes[{b,d}]);
adj[nodes[{b,d}]].push_back(nodes[{a,c}]);
adj[nodes[{a,d}]].push_back(nodes[{b,c}]);
adj[nodes[{b,c}]].push_back(nodes[{a,d}]);
}
}
int start = nodes[{0,n-1}];
int ans = 1e9+7;
std::queue<int> q;
q.push(start);
std::vector<int> dist(node+1,-1);
dist[start] = 0;
std::vector<bool> visited(node+1,false);
visited[start] = true;
auto it = nodes.begin();
while(!q.empty()){
int cur_node = q.front();
q.pop();
for(int i = 0; i < (int)adj[cur_node].size();++i){
int next_node = adj[cur_node][i];
if(!visited[next_node]){
q.push(next_node);
visited[next_node] = true;
dist[next_node] = dist[cur_node] + 1;
}
}
}
for(int i = 0; i < n;++i){
for(int j = 0; j < n;++j){
int node = nodes[{i,j}];
if(node == 0)
continue;
if(dist[node] == -1)
continue;
if(i == j || (exist[i][j] == 1)){
ans = std::min(ans,dist[node]);
}
}
}
if(ans == 1e9+7)
ans = -1;
std::cout << ans << "\n";
}
这个程序甚至在进入 main 之前就给出了分段错误,我尝试使用 gdb,它也说错误在 int main()
行。我完全不明白发生了什么,我也尝试 运行 在 C++ 14 和 C++ 17 上运行程序,它 运行 很好,但我使用的是 C++ 11,它编译成功但没有't 运行。请帮助我。
您在堆栈中的代码中分配了超过 200 万 std::vector
s。通常堆栈不是很大,所以肯定会超过保留的 space 并导致问题。局部对象的分配发生在函数中的任何代码 运行 之前,因此看起来它在函数中崩溃但在您的任何代码 运行.
std::vector<int> adj[N];
如果您需要那么多向量,则需要动态分配它。
首先,这不是有效的 C++:
int n;
cin >> n;
int exist[n][n]; // <-- not valid C++
C++ 中的数组的大小必须由编译时表达式表示,而不是运行时值。 C++ does not support variable-length arrays.
已编译的代码,因为有些编译器默认支持此功能。但它仍然不受 C++ 语言规范的支持。例如,Visual C++ 编译器不支持这种语法。如果您尝试使用 Visual C++ 编译代码,您会收到相应的错误消息。
即使支持,较大的 n
值也可能会破坏堆栈内存,因为堆栈内存是有限的。
那么第二个问题就是你有这个:
std::vector<int> adj[N];
如果N
很大,那就是N
std::vector<int>
的数组。同样,这很可能会耗尽堆栈内存。
一种解决方案是使用 std::vector<std::vector<int>>
:
std::vector<std::vector<int>> exist(n, std::vector<int>(n));
//...
std::vector<std::vector<int>> adj(N):
由于 vector 从堆中获取内存,因此堆栈内存耗尽问题消失了。