簡體   English   中英

scanf中的分段錯誤

[英]Segmentation fault in scanf

在運行此代碼時,我在scanf()遇到分段錯誤。 這可能是由於大型數組的聲明(我通過注釋數組聲明對其進行了檢查)。

#include<stdio.h>
int main()
{
    int test;
    //int n,ok,counter,i,j;
    char a[1000][1000];
    int x[1000][1000],y[1000][1000];
    scanf("%d",&test);
    printf("%d",test);
    return 0;
}

由於我需要這些數組,因此有人可以建議我如何更正此代碼。

問題是您正在本地定義一些大對象。 局部變量在堆棧上創建,並且堆棧有限制(每個線程)。 有時,堆棧最大可以為1 MB。 您的數組將遠遠超出此范圍。 我的猜測是您實際上溢出了堆棧。 您可以將數組定義移到main之外,並且您的程序應該可以運行,因為不會在堆棧上創建這些數組。 您也可以通過在main中將它們static來定義數組。 這與在外部聲明它們具有相同的效果。

全局定義的變量(包括未初始化的數組)和static未初始化的變量(即使它們在函數中)通常放在數據段中,並在運行程序時進行初始化。 還保證將它們設置為全0。此Wiki參考將C中的此數據區域描述為:

C中的BSS

在C中,沒有顯式初始化程序的靜態分配對象被初始化為零(對於算術類型)或空指針(對於指針類型)。 C的實現通常使用僅由零值位組成的位模式來表示零值和空指針值(盡管C標准不需要)。 因此,BSS部分通常包括在文件作用域(即,任何函數外部)聲明的所有未初始化變量,以及使用static關鍵字聲明的未初始化局部變量。 一個實現還可以將靜態初始化變量分配給bss部分,該變量由僅包含零值位的值初始化。

BSS段沒有像堆棧那樣受到約束。 如果資源存在並且您沒有超出任何進程配額,則BSS可能會用盡可用內存。

另一種選擇是使用malloc動態分配數組,這會將它們放在堆中。 以下代碼是創建數組的最簡單方法。 我使用#define來弄清楚什么是行和列。 在定義了這些陣列並分配了內存之后,它們可以像任何常規2D陣列一樣使用。

#include<stdio.h>
#include<stdlib.h>
int main()
{
    #define ROWS 1000
    #define COLUMNS 1000
    int test;

    char (*a)[COLUMNS] = malloc(ROWS * sizeof *a);
    int  (*x)[COLUMNS] = malloc(ROWS * sizeof *x);
    int  (*y)[COLUMNS] = malloc(ROWS * sizeof *y);

    a[100][20] = 'X';
    x[4][999] = 666;
    y[500][0] =  42;

    scanf("%d",&test);
    printf("%d",test);

    free(a);
    free(x);
    free(y);

    return 0;
}

您正在堆棧上分配大量內存,這會導致堆棧溢出 在這種情況下,應使用malloc() ,它將在堆上分配內存。 另外,使用后還需要free()內存。

這是您可以使用的示例代碼,我只對a變量執行了此操作,您可以對xy變量使用類似的代碼:

#include<stdio.h>
#include<stdlib.h>
int main()
{
    char **a; 
    int i, j;
    a = malloc(1000*sizeof(char*));
    for(i=0;i<1000;i++)
    {
        a[i] = malloc(1000*sizeof(char));
        for(j = 0; j < 1000; j++)
        {
            //Your operations
        }
    }
    for(i=0; i< 1000; i++)
        free( a[i]);
    free(a);
    return 0;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM