2012-02-09 23 views
8

Theo this reddit comment thread, nó không xác định được nếu một nỗ lực được thực hiện để đọc bộ nhớ trước khi nó được ghi vào. Tôi đang đề cập đến bộ nhớ heap bình thường đã thành công malloc ed.đọc trước khi ghi là không xác định với bộ nhớ malloced?

... lưu ý rằng đây không phải là hợp lệ C: hệ thống trình biên dịch/thời gian chạy được phép khởi tạo bộ nhớ không khởi tạo với biểu diễn cái bẫy gọi là hành vi không xác định khi truy cập.

Tôi thấy khó tin. Có báo giá chuẩn không?

Tất nhiên, tôi hiểu rằng không có gì đảm bảo rằng bộ nhớ đã bị xóa. Các giá trị trong bộ nhớ uninitialized này về cơ bản là giả ngẫu nhiên hoặc tùy ý. Nhưng tôi thực sự không thể tin rằng tiêu chuẩn sẽ ám chỉ điều này là hành vi không xác định (theo nghĩa là nó có thể phân đoạn hoặc xóa tất cả các tệp của bạn hoặc bất kỳ tệp nào). Phần còn lại của chuỗi reddit không có thêm chút ánh sáng nào về vấn đề này.

+0

Erm, bạn nghĩ hành vi không xác định nghĩa là gì? (Có, sử dụng bộ nhớ phân bổ trước khi nó được khởi tạo tạo ra hành vi không xác định) –

+1

@Brian Tôi giả sử anh ta hỏi liệu toàn bộ hành vi (tức là segfault này) là không xác định, hoặc chỉ là giá trị mà kết quả từ việc đọc. – Owen

+0

@Owen, đúng vậy, tôi đã cập nhật câu hỏi cho phù hợp. –

Trả lời

10

Nếu truy cập thông qua char*, điều này được xác định. Nhưng nếu không, đây là hành vi không xác định.

(C99, 7.20.3.3) "Hàm malloc phân bổ không gian cho đối tượng có kích thước được chỉ định theo kích thước và giá trị không xác định."

trên giá trị không xác định:

(C99, 3.17.2p1) "giá trị không xác định: hoặc là một giá trị không xác định hoặc một đại diện bẫy"

trên đại diện bẫy đọc qua một phi -character loại hành vi không xác định:

(C99, 6.2.6.1p5) "Một số biểu diễn đối tượng nhất định không cần đại diện cho một giá trị của kiểu đối tượng. Nếu giá trị được lưu trữ của một đối tượng có biểu diễn như vậy và được đọc bởi một biểu thức lvalue không có kiểu ký tự, hành vi là không xác định. [... ] Một biểu diễn như vậy được gọi là biểu diễn bẫy. "

+1

Thêm một báo giá tiêu chuẩn cho biết rằng truy cập vào một kết quả đại diện bẫy trong hành vi không xác định, và bạn sẽ có chuỗi hoàn chỉnh. (Nhưng, theo nhận xét này, bạn vẫn còn thiếu một bình luận đó.) –

+0

@BrooksMoses done – ouah

+0

@BrooksMoses, đó là câu hỏi lớn. "Đại diện bẫy" nghĩa là gì? –

1

ISO/IEC 9899:1999, 7.20.3.3 Hàm malloc:

Hàm malloc phân bổ không gian cho một đối tượng có kích thước được xác định bởi kích thước và có giá trị là không xác định.

6.2.6.1 Đại diện các loại, §5:

Một số cơ quan đại diện đối tượng không cần phải đại diện cho một giá trị của các loại đối tượng. Nếu giá trị được lưu trữ của một đối tượng có biểu diễn như vậy và được đọc bởi một biểu thức giá trị không không có loại ký tự, hành vi không xác định.

Và chú thích 41 làm cho nó thậm chí còn rõ ràng hơn (ít nhất là cho các biến tự động):

Do đó, một biến tự động có thể được khởi tạo một đại diện bẫy mà không gây ra hành vi không xác định, nhưng giá trị của biến không thể được sử dụng cho đến khi một giá trị thích hợp được lưu trữ trong nó.

+0

Tôi không có vấn đề với 'giá trị không xác định'. Điều đó rõ ràng trong câu trả lời. Câu hỏi đặt ra là liệu hành vi là hoàn toàn không xác định (segfaults và vv). –

+1

Vì vậy, nó là OK thông qua 'char *'? Bạn có thể đưa ra một ví dụ về một đối tượng như vậy không? Tôi đang cố gắng để nhớ làm thế nào 'đôi' được đại diện - có lẽ không phải tất cả các bit-cấu hình bản đồ để hợp lệ 'đôi'. Đây có phải là loại điều được nhắc đến ở đây không? –

+1

Có nhiều loại giá trị 'NaN' (" không phải số ") là một phần của biểu diễn chuẩn' đôi', nhưng những giá trị đó vẫn "hợp lệ". –

2

Nó hợp lý phải không xác định. Nếu không, hành vi cần thiết của một chương trình C chạy dưới cái gì đó như Valgrind, trong đó chẩn đoán lần đọc của bộ nhớ uninitialized và ném lỗi thích hợp khi chúng xảy ra, sẽ là bất hợp pháp theo tiêu chuẩn.

Đọc tiêu chuẩn, câu hỏi quan trọng là liệu giá trị của bộ nhớ malloc'ed là "giá trị không xác định" (phải là giá trị có thể đọc được) hay "giá trị không xác định" (có thể chứa biểu diễn bẫy; 2.)

Theo 7.20.3.3, được trích dẫn trong các câu trả lời khác, malloc trả về một khối bộ nhớ chứa các giá trị không xác định và do đó có thể chứa các biểu diễn bẫy. Thảo luận có liên quan về biểu diễn bẫy là 6.2.6.1, phần 5:

Biểu diễn đối tượng nhất định không cần đại diện cho giá trị của loại đối tượng. Nếu giá trị được lưu trữ của một đối tượng có một biểu diễn như vậy và được đọc bởi một biểu thức giá trị không có kiểu ký tự, hành vi này là không xác định. ... Biểu diễn như vậy được gọi là biểu tượng bẫy .

Vì vậy, có bạn đi. Về cơ bản, việc triển khai C được phép phát hiện (ví dụ: "bẫy") tham chiếu đến các giá trị không xác định và xử lý lỗi đó theo cách mà nó chọn, bao gồm cả các cách không xác định.

+0

Tại sao cần thiết các công cụ như Valgrind hoạt động như các triển khai C hoàn toàn phù hợp? Tôi sẽ đề nghị rằng trong nhiều trường hợp nó sẽ hữu ích hơn cho họ để được cấu hình để bẫy trên nhiều thứ được coi là hoàn toàn xác định bởi các tiêu chuẩn nhưng lập trình viên biết sẽ không bao giờ xảy ra ngoại trừ do tai nạn. – supercat

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