2009-06-01 22 views
5

Kết quả của việc áp dụng (dưới) là như sau:Đối với loop thiếu nhiều chỉ số với segfault

tử số index: 0 nội dung Element: 22
tử số index: 1 phần tử nội dung: 22
chỉ số phần tử số: 2 nội dung Element: 22
tử số chỉ mục: 3 nội dung Element: 22
tử số chỉ số: 4 nội dung Element: 22
tử số chỉ số: 22 nội dung tố: 134513712

Tại sao các phần tử chỉ mục có nhãn 5 - 21 bị bỏ sót? Tôi hiểu mã này có thể segfault làm để giới hạn của mảng đang tràn, nó được thiết kế để làm điều đó, tôi không quan tâm đến lý do tại sao mã này là xấu, chỉ là lý do tại sao một số chỉ số được bỏ qua.

#include <stdio.h> 
int main(){ 

int array[5]; 

int i; 
for(i=0; i<10; ++i){ 
    array[i] = 22; 
    printf("Element index number: %d Element contents: %d\n", i, array[i]); 
} 
return 0; 
} 
+1

Xem câu hỏi tương tự http://stackoverflow.com/questions/795194/too-many-elements-in-an-array –

Trả lời

7

Điều đang xảy ra là khi bạn ghi vào mảng [5] bạn đang viết thư cho tôi. Chúng liền kề trên chồng, trong bộ nhớ, vì vậy đây là hành vi bạn có thể mong đợi.

Hãy suy nghĩ về nó theo cách này,

bạn đã thực hiện một mảng với 5 yếu tố tại

int array[5]; 

trong thực tế, mảng chỉ là một địa chỉ. số trong [] xác định khoảng cách quá xa đến địa chỉ đó để truy cập. Vì vậy:

  • array [0] 0 ints trong bộ nhớ qua địa chỉ "mảng"
  • array [1] là 1 ints trong bộ nhớ địa chỉ qua "mảng" ...
  • mảng [4] là 4 ints trong bộ nhớ qua địa chỉ "mảng" (int cuối cùng bạn dành riêng cho mảng)

vì vậy nếu bạn nhận được tất cả các cách để

  • mảng [5] là 5 ints trong bộ nhớ p địa chỉ ast "array"

Không có giới hạn kiểm tra tự động trong C, vì vậy rất vui khi ghi đè bộ nhớ của riêng bạn. Bạn đã đặt "i" sau mảng [5] trong ngăn xếp, rất có thể mảng [5] là i.

Bạn chỉ cần đặt mảng [5], hoặc i, thành 22, do đó tôi là 22. Bây giờ tôi là 22, lần tra cứu tiếp theo của bạn, thành mảng [i] thực sự là mảng [22]. Điều này lấy bất cứ điều gì rác xảy ra được ở vị trí đó trong bộ nhớ; hoặc nếu bạn may mắn, bị treo.

+0

"khi bạn ghi vào mảng [6] bạn đang viết cho tôi" nên là 'mảng [5]', như bạn một cách chính xác viết sau. –

+1

Lưu ý rằng mảng kết thúc và tôi bắt đầu là triển khai và kiến ​​trúc phụ thuộc, do đó trên một trình biên dịch khác, phiên bản hệ điều hành khác nhau, hệ điều hành khác nhau hoặc kiến ​​trúc khác nhau, bạn có thể nhận được kết quả hoàn toàn khác nhau. –

9

Khi bạn tràn bộ nhớ được cấp phát, bạn đang ở "lãnh thổ không xác định". Có lẽ mảng ghi đã viết vào nơi "i" được lưu trữ trên ngăn xếp. Lưu ý rằng không giống như các ngôn ngữ như Java và C#, C không kiểm tra giới hạn thời gian chạy, vì vậy nó không đảm bảo thực hiện bất cứ điều gì hữu ích (như segfault) khi bạn chạy quá nhiều mảng hoặc chuỗi hoặc bộ nhớ malloced. Nó không được đảm bảo để làm bất cứ điều gì. Nó có thể sụp đổ, nó có thể tiếp tục chạy, it could cause demons to fly out your nose.

+6

Đây chính xác là những gì đang diễn ra. "mảng" và "i" đều được lưu trữ trên ngăn xếp, với "i" ngay sau "mảng". Vì vậy & mảng [5] đề cập đến cùng một vị trí như & i. Việc ghi vào mảng [5] sẽ ghi vào giá trị được lưu trữ tại vị trí của i trên ngăn xếp. Trong vòng lặp của bạn, bạn đang viết 22 cho i khi mảng tràn, do đó nhảy từ 4 đến 22. –

0

Nhiều khả năng bộ nhớ cho biến cục bộ "i" được đặt ngay sau "mảng" trên ngăn xếp, do đó, & mảng [5] == & i, có nghĩa là bạn đang chỉ định 22 cho "i" khi bạn chỉ định 22 thành mảng [5].

-1

Bạn đã khai báo một mảng gồm 5 int, nhưng vòng lặp for của bạn ghi giá trị vào 10 mục nhập.

Thay đổi

int array[5]; 

để

int array[10]; 
+0

xin lỗi ... downvote vì bạn có lẽ thậm chí không đọc câu hỏi: ... giới hạn của mảng bị tràn, nó được thiết kế để làm điều đó, tôi không quan tâm đến lý do tại sao mã này là xấu ... –

2

@Doug có nó, nhưng chúng ta hãy mở rộng nó một chút.

Bạn có mảng [5] và i là biến tự động, vì vậy chúng được phân bổ trên ngăn xếp tại mục nhập, vì vậy bạn phân bổ 6 ô: mảng [0], mảng [1], ... mảng [4] và sau đó là i.

Khi bạn đặt i thành 5, mảng [i] trỏ đến ô trên ngăn chứa i. Sau đó bạn chỉ định 22 cho nó. Vì vậy, bây giờ tôi = 22, như bạn in.

Sau đó, bạn nhận được mảng [i] hoặc mảng [22], bị tắt ở cuối của stck; giá trị ngẫu nhiên xảy ra là số lượng lớn.

+0

đặt tốt. câu trả lời của ai đó cần phải thêm chi tiết đó "Sau đó, bạn nhận mảng [i] hoặc mảng [22] ..." –

+0

oops Tôi vừa thêm tất cả điều này, không chắc chắn một trong số chúng tôi đã nói nó trước tiên. +1 cho bạn –

+0

Chúng tôi đã vượt qua - và tôi đã +1 bạn vì lý do tương tự. –

Các vấn đề liên quan