2010-08-31 36 views
8

Chương trình được xác định giả định của tôi tạo ra một trong số ít kết quả đầu ra hơi khác nhau trên các lần chạy khác nhau. Đầu vào, trình biên dịch và máy tính không thay đổi. Tôi không chắc đầu ra nào là đúng bởi vì nó luôn có vẻ hợp lý.Nguồn không xác định

Bên cạnh cuộc gọi đi lạc tới rand(), làm thế nào điều này có thể thực hiện được?

+7

Chúng tôi sẽ cần xem một số mã trước khi chúng tôi đưa ra các suy đoán hoang dã. –

+2

Mã của bạn có chứa bất kỳ thứ gì đi vào vùng đất của hành vi không xác định không? –

+1

Ai nói các trình biên dịch là xác định? – AshleysBrain

Trả lời

16

Trong nhiều cách:

  • sử dụng nhiều chủ đề theo cách liên quan đến một số điện thoại data race,
  • g hệ thống thời điểm hiện tại như là đầu vào,
  • sử dụng các biến chưa được khởi tạo,
  • ...

Chúng tôi chắc chắn có thể làm nhiều hơn dự đoán, nhưng nếu bạn muốn nhận được sự giúp đỡ có ý nghĩa, có lẽ nó sẽ là tốt cho bạn để xuất bản các phần có liên quan của mã của bạn :-)

+0

Có; chúng ta cần mã! Tất nhiên, tất cả các yếu tố này cũng như các lỗi thập phân và giả ngẫu nhiên là xác định về mặt kỹ thuật khi chúng chạy trên một máy xác định. Chúng chỉ xuất hiện không xác định đối với chúng tôi khi chúng tôi không thể theo dõi hoặc hiểu được các yếu tố đầu vào và hàng triệu trạng thái tiến bộ của chương trình của chúng tôi trong bối cảnh hệ thống chia sẻ thời gian được kiểm soát ít cá nhân hơn. Lý do tại sao lý thuyết và khoa học máy tính luôn quan trọng để dạy cùng với các kỹ năng lập trình hạt và bu lông. –

+0

Tôi nên nói rõ rằng tôi chỉ muốn có một danh sách các khả năng chung, đó là những gì tôi nhận được. Cảm ơn. – zoo

7

Nó có thể là:

  • Chủ đề thời gian
  • Bất kỳ loại đầu vào (sử dụng, tập tin, mạng, vv)
3

Nếu không nhìn thấy một số mã (HINT HINT), tốt nhất tôi có thể nghĩ là sẽ tìm mẫu. Có lẽ ngày nào đó cụ thể.

Ngoài ra, hãy thử tìm kiếm điều kiện chủng tộc. Điều đó có thể trông không xác định.

7

Nếu đầu ra của bạn phụ thuộc vào địa chỉ cấp phát trên heap:

int main(int argc, char* argv[]) 
{ 
    printf("%p", malloc(42)); 
    return 0; 
} 

Đối với mỗi lần chạy, các malloc() có thể trở lại một địa chỉ khác ảo - chưa kể đến NULL trong trường hợp việc phân bổ thất bại.

+2

Bắt tốt. Heap/stack ngẫu nhiên địa chỉ là một tính năng khá tiêu chuẩn hiện nay. Điều đó sẽ có hiệu lực nếu con trỏ được sử dụng như là chìa khóa ở đâu đó. Tôi đã sử dụng nó trong vài lần để làm cho sắp xếp ổn định (nếu các phím bằng nhau, so sánh các con trỏ). – Dummy00001

+0

Mặc dù, bạn phải khá kém may mắn/chạy trên bộ nhớ rất thấp để có lỗi phân bổ. – zneak

+0

Đầu ra sẽ phụ thuộc vào địa chỉ được phân bổ trên heap nếu đối tượng được phân bổ heap được sắp xếp theo địa chỉ của chúng, ví dụ nếu con trỏ đến chúng được lưu trữ trong vùng chứa có thứ tự như một tập hợp. – Richard

2

Sử dụng giá trị của con trỏ thay vì con trỏ trỏ đến luôn tạo ra kết quả thú vị.

5

Bên cạnh một cuộc gọi đi lạc để rand()

rand() là hoàn toàn xác định chừng nào bạn ăn nó hạt giống ban đầu tương tự.

0
  • Đầu vào từ mạng/internet.
  • ngày/giờ
1

Trong các chương trình mà không tương tác nhiều với "thế giới bên ngoài", nguồn tin phổ biến của phi nghĩa quyết định là sự phụ thuộc vào so sánh con trỏ. Đôi khi bạn có thể nhìn thấy nó trong mã: khi một hàm so sánh từ điển vượt quá mọi thứ để so sánh (mọi thứ đều bằng nhau), nó so sánh các địa chỉ của các đối tượng là phương sách cuối cùng. Điều này có thể tạo ra các thứ tự khác nhau nếu các đối tượng được cấp phát trong bộ nhớ động, vì các vị trí phân bổ thực tế có thể khác nhau từ nền tảng đến nền tảng và từ chạy đến chạy.

0

Bạn không cung cấp nhiều thông tin. Tuy nhiên, với tư cách là người lập trình thời gian thực để kiếm sống những thủ phạm có khả năng nhất mà tôi tìm kiếm khi những điều như vậy xảy ra là:

  • Sử dụng bộ nhớ chưa được khởi tạo.
  • Điều kiện chủng tộc.
  • Một số kết hợp tối nghĩa ở trên.

Ví dụ: một sự cố mà tôi từng gặp phải trong thư viện được chia sẻ không bị "chia sẻ" như tôi nghĩ, và cố gắng sử dụng một xử lý từ một quy trình để lập chỉ mục một bảng chưa được khởi tạo trong một quá trình thứ hai. Tùy thuộc vào cách mọi thứ khởi động mà có thể hoặc có thể không gây ra dữ liệu quan trọng trong một quá trình thứ ba để chuyển vào thùng rác.

0

Bất kỳ hành vi không xác định nào. tức là: sẽ mất hàng trăm trang để giải thích mọi nguồn có thể thay đổi đầu ra. Thử gỡ lỗi để tìm số nơi xảy ra thay đổi hoặc đọc một số thông số C++.

3

Nếu chương trình của bạn sử dụng float/double, có thể có sự khác biệt trong kết quả nếu có chuyển ngữ cảnh trên một số kiến ​​trúc.

Trên x86, FPU sử dụng độ chính xác mở rộng cho kết quả trung gian, nhưng khi được lưu trong bộ nhớ (xảy ra khi có chuyển đổi ngữ cảnh hoặc quy trình hoặc luồng), độ chính xác đó bị mất. Điều đó có thể gây ra một số phân kỳ nhỏ của kết quả (chúng tôi đã phát hiện vấn đề như vậy trong chương trình của chúng tôi). Một cách để tránh vấn đề này là yêu cầu trình biên dịch không sử dụng FPU nhưng SSE cho các hoạt động điểm nổi.

http://www.network-theory.co.uk/docs/gccintro/gccintro_70.html

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