C++代码在Ubuntu编译运行异常,Visual Studio正常,求排查原因
问题分析与解决方案
你的代码在Ubuntu下运行出现垃圾值和段错误,核心原因是内存分配时的类型不匹配——Windows的MSVC编译器对这种不规范的强制转换更为宽容,才没有触发问题,而Linux下的g严格遵循C标准,直接暴露了代码的错误。
具体错误点
看这段内存分配的代码:
int ***trtr = (int ***)new int[n]; for (int i = 0; i < n; i++) { trtr[i] = (int **)new int[m]; }
- 你要创建的是三维指针(
int***),但第一步new int[n]分配的是n个int类型的内存块,却被强制转换成了int***类型,这完全违背了C++的类型规则,属于未定义行为。 - 同理,第二个循环里
new int[m]分配的是int数组,强制转成int**,同样是类型不匹配。
这种错误会导致内存布局混乱,访问指针时要么读取到垃圾数据,要么直接触发内存访问违规(段错误)。
修正后的代码
把内存分配部分改成正确的类型匹配,同时补充内存释放逻辑避免泄漏:
#include <iostream> using namespace std; int ***lol(int *a, int n, int m) { // 第一步:分配n个int**类型的指针 int ***trtr = new int**[n]; for (int i = 0; i < n; i++) { // 第二步:每个int**分配m个int*类型的指针 trtr[i] = new int*[m]; } for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { trtr[i][j] = &a[i * m + j]; } } return trtr; } int main() { int n, m; cin >> n >> m; int *a = new int[n * m]; for (int i = 0; i < n * m; i++) a[i] = i; int ***kekl = lol(a, n, m); for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { cout << *kekl[i][j] << " "; } cout << endl; } // 释放分配的内存,避免内存泄漏 for (int i = 0; i < n; i++) { delete[] kekl[i]; } delete[] kekl; delete[] a; return 0; }
额外说明
- 启用注释部分后直接段错误,是因为错误的指针类型导致你试图往非法内存地址写入数据,直接触发了内存访问违规。
- 日常写C++代码时,尽量避免不必要的强制类型转换,编译器的类型检查是帮你规避错误的重要手段。
内容的提问来源于stack exchange,提问作者Edwin Paco
相关产品推荐
相关产品推荐

