[英]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.c
和bag.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.