【发布时间】:2019-12-24 19:36:43
【问题描述】:
SO(双关语)我想从 HackerEarth 解决这个问题:https://www.hackerearth.com/practice/data-structures/arrays/multi-dimensional/practice-problems/algorithm/the-wealthy-landlord/
这是我的代码:
#include <stdio.h>
#define ll long long
int main () {
ll int N;
scanf("%d", &N);
ll int i, j, a, b;
ll int TOTAL;
typedef struct {
ll int flag;
ll int count;
// int fc[N]; // farmer cost OR cost for farmer i
ll int *fc;
} land;
// check whether all of them have been
// initialised to 0
// printf("%d ", arr[2][2].count);
// yes
land arr[1000][1000];
for(i=0; i<1000; i++) {
for(j=0; j<1000; j++) {
arr[i][j].fc = (ll int *)calloc(N, sizeof(ll int));
}
}
ll int x1, y1, x2, y2, c;
ll int ta, tb; // temp a // temp b
for(i=0; i<N; i++) {
scanf("%lld %lld %lld %lld %lld", &x1, &y1, &x2, &y2, &c);
// the array index starts from 0
// so to match the inputs to the correct indices
// the inputs must be reduced by one
for(a=x1; a<=x2; a++) {
for (b=y1; b<=y2; b++) {
ta = a-1;
tb = b-1;
arr[ta][tb].count++;
if(arr[ta][tb].count >= 2)
arr[ta][tb].flag = 1;
arr[ta][tb].fc[i] = c;
}
}
}
ll int k;
for(i=0; i<1000; i++) {
for(j=0; j<1000; j++) {
if (arr[i][j].flag == 1) {
for(k=0; k<N; k++)
TOTAL += arr[i][j].fc[k];
}
}
}
printf("%lld", TOTAL);
return 0;
}
结果:运行时错误 (SIGSEGV)
编译日志: 编译成功
执行日志:执行失败。
分段错误:发生这种情况 因为导致缓冲区的超出范围的数组索引 溢出、错误初始化的指针等。信号是 当程序尝试在外部读取或写入时生成 分配给它的内存或写内存只能是 读。例如,您正在使用不支持的语言访问 a[-1] 支持数组的负索引。
我已多次编辑此代码并通过查看各种 SO 问题修复了各种问题。现在它非常接近工作,但它只是板着脸说分段错误。最糟糕的故障,几乎没有提示您应该如何修复它。我没有主意了!
另外 - 可能有更好的方法来解决这个问题,它不涉及二维结构数组中的数组,但我很想学习如何解决这个分段错误。
【问题讨论】:
-
哪一行代码导致了段错误?
-
对我来说,
land arr[1000][1000];行看起来有点可疑。您要求在堆栈上创建一个大小 >= 2400 万字节的自动变量!如果这不会导致堆栈溢出,我不确定会发生什么。 (您可以尝试从main移出并改成static- 这不是最好的代码,我同意,但它可能有助于诊断。) -
使用 MSVC (VS2019) 编译时,我收到此警告(以及其他一些警告):警告 C6262:函数使用堆栈的 '24000112' 字节:超过 /analyze:stacksize '16384 '。考虑将一些数据移动到堆中。
-
@AdrianMole 非常感谢您的反馈!至少现在我知道哪些线路导致了问题。在大学里,我们几乎没有开始使用数据结构(只完成了数组)。这意味着我对堆栈和堆一无所知嘿嘿,我应该尝试一种更简单的方法来解决问题。只是出于好奇,我很想看看这段代码在更正后会是什么样子。
标签: c arrays data-structures segmentation-fault dynamic-memory-allocation