2-D结构数组->无法修复分段错误:(

问题描述 投票:0回答:1

所以(双关语是我的意思)我想从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)

编译日志:编译成功

执行日志:执行失败。分段错误:发生这种情况由于范围外的数组索引导致缓冲区溢出,指针初始化不正确等。当程序尝试在外部读取或写入时生成为其分配的内存或写入只能为读。例如,您正在以一种不支持数组的负索引。

我已经多次编辑此代码,并通过查看各种SO问题解决了各种问题。现在它已经很接近工作了,但是它只是张直的脸并说出了分割错误。最严重的故障,几乎没有提示应如何解决。我没主意!

ALSO-可能有一个更好的方法来解决此问题,该方法不涉及结构的二维数组中的数组,但我很想学习如何解决此分段错误。

c arrays data-structures segmentation-fault dynamic-memory-allocation
1个回答
1
投票

您的行:land arr[1000][1000];声明arrautomatic变量,这意味着从stack为其分配了空间。简而言之,此stack是在调用函数时分配给本地使用的内存(而main实际上只是操作系统在运行程序时调用的函数)。

通常,堆栈上的可用空间是有限的-通常为16-64 KB。但是,您的arr变量(假设long long int为8个字节,指针为8个字节)将需要大于24兆字节。几乎可以肯定,这就是导致您的“堆栈溢出!”

对此问题的“快速解决方案”是声明变量static。这意味着空间是在编译时(或更可能是在链接时)分配的,并在程序运行时“锁定”到内存中。 (执行此操作后,您可能会注意到可执行文件的大小增加了24 MB,具体取决于您的平台!)

这里是您的代码的稍作修改的版本,经过了更正,以及其他一些建议的改进(所有标记为“ ///”注释定界符:

#include <stdio.h>
#include <stdlib.h>

#define ll long long 

int main() {
    ll int N;
    scanf("%lld", &N); /// The plain "%d" format expects an "int" argument - use "%lld" for "long long int"
    ll int i, j, a, b;
    ll int TOTAL = 0;  /// If you don't INITIALIZE "TOTAL" it could start off with ANY value whatsoever!

    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

    static land arr[1000][1000]; /// Without "static" this array (~ 24 Megabytes) will overflow the stack!
    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;
}

随时要求进一步的澄清和/或解释。

© www.soinside.com 2019 - 2024. All rights reserved.