簡體   English   中英

初始化帶有數組的結構時出現分段錯誤

[英]Segmentation fault when initializing struct w/ arrays

我正在用C寫ncurses Scrabble克隆。

我已經編寫了一些代碼來表示袋子,這是可以將字符拖出的亂序字符的來源,就像在現實生活中從袋子中隨機抽出瓷磚一樣。

我的代碼可以在OS X上運行-但是,當我嘗試在Debian機器上進行編譯時,它給了我這個直截了當的消息:

~/nscrabble $ ./scrabble
Segmentation fault

我已經使用gdb嘗試診斷問題。 似乎段錯誤是在return語句上引起的:

(gdb) run
Starting program: /home/jay/nscrabble/scrabble 

Program received signal SIGSEGV, Segmentation fault.
0x0000000000400ca8 in bag () at bag.c:53
53          return b;
(gdb) 

妳去 這是代碼( bag.cbag.h )這是bag.h

#ifndef BAG_H_INCLUDED
#define BAG_H_INCLUDED

/*
 * This array states how many times each
 * letter should show up in the bag.
 *
 * distributions[0]     Number of As
 * distributions[1]     Number of Bs
 * ...
 * distributions[25]    Number of Zs
 * distributions[26]    Number of blank tiles
 */
const short distributions[27];

/*
 * The bag is the repository of tiles in Scrabble.
 * I didn't want to deal with storing pointers
 * and freeing them constantly, so I decided to
 * store chars.
 */
typedef struct bag {
        char tiles[100];
        size_t top;

        /*
         * Get a tile letter out of the bag.
         * It removes the letter from the bag.
         */
        char (*pop)( struct bag* );
} bag_t;

/*
 * The constructor.
 * Get a new bag using this.
 */
struct bag bag();



char bg_pop( struct bag* );

#endif

這是bag.c

#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include "bag.h"

const short distributions[27] = {
        9, 2, 2, 4, 12, 2, 3, 2, 9, 1, 1, 4, 2, 6, 8, 2, 1, 
        6, 4, 6, 4, 2, 2, 1, 2, 1, 2
};

char bg_pop( struct bag* b )
{
        return b->tiles[b->top--];
}

struct bag bag()
{
        struct bag b;
        for( char letter = 'A', count = 0; letter <= ']'; letter++ ) {
                for(int i = 0; i < distributions[letter - 65]; i++, count++)
                        b.tiles[count] = letter;
        }
        srand( time(NULL) );
        for( int i = 0; i < 3; i++, rand() )
                ;
        for( int i = 0; i < 98; i++ ) {
                int n = (rand() % (100 - i)) + i;
                char temp = b.tiles[i];
                b.tiles[i] = b.tiles[n];
                b.tiles[n] = temp;
        }
        b.top = 100;
        b.pop = bg_pop;
        return b;
}

scrabble.c:

#include <stdio.h>
#include "bag.h"

int main( int argc, const char** argv )
{
        struct bag b = bag();

        for( int i = 0; i < 100; i++ )
                printf("%3c", b.tiles[i]);
}

我知道改組是正確完成的(至少在OS X上是這樣)。

有人可以幫忙弄清楚這里發生的事情嗎?

這里:

for( char letter = 'A', count = 0; letter <= ']'; letter++ ) {
    for( int i = 0; i < distributions[ letter - 65 ]; i++, count++ ) {
        b.tiles[count] = letter;
    }
}

如果您打印出count的值,您會發現它的值高達152,遠高於數組中的100個元素。 您似乎正在斷斷續續,因為這會使系統中的count變為負數,因為您已將其定義為在系統上簽名的char

您可以將其定義為int ,當我這樣做時,segfault對我來說就消失了,但是您仍然無法超出數組的范圍,因此使用count的邏輯顯然存在問題。 或者,更有用的是,您有一對循環,可吐出152個字母,但您只為其中的100個預留了內存,因此您制作的字母多於空間。

如果將letter <= ']'更改為letter <= '[' (因為ASCII表中的'['緊跟在'Z'之后),則一旦count達到100,循環就正確退出,應該進行設置。

您超出了第21行的數組范圍:

b.tiles[count] = letter;

要在gdb中看到此內容:

gdb blah
b 21
cond 1 count >= 100
run

如果你去高足以與count上面,你會在堆棧上垃圾的返回地址,這就是為什么你在段錯誤的return

暫無
暫無

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

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