2012-05-15 40 views
6

đọc về nó here.Cách triển khai tính tham chiếu trong C?

Tôi cần triển khai một biến thể của giao diện như vậy, giả sử chúng ta có một không gian bộ nhớ lớn để quản lý nên có các hàm getmem (kích thước) và miễn phí (con trỏ để chặn).) thực sự có thể giải phóng bộ nhớ nếu và chỉ khi tất cả các quá trình sử dụng khối đó được thực hiện bằng cách sử dụng nó.

Điều tôi đang nghĩ đến là xác định cấu trúc Collectable làm con trỏ để chặn, kích thước và quy trình sử dụng số đếm. sau đó bất cứ khi nào một quá trình sử dụng một ví dụ cấu trúc Collectable lần đầu tiên nó phải tăng số lượng rõ ràng, và bất cứ khi nào quá trình free() của nó, đếm được giảm đi.

Vấn đề với cách tiếp cận này là tất cả các quy trình phải đáp ứng với giao diện đó và làm cho nó hoạt động rõ ràng: bất cứ khi nào gán con trỏ thu được cho một cá thể, quy trình phải rõ ràng là bộ đếm đó không thỏa mãn tôi. là cách để tạo macro cho điều này xảy ra ngầm định trong mọi bài tập?

Tôi đang tìm cách để tiếp cận vấn đề này trong một thời gian, vì vậy phương pháp và ý tưởng khác sẽ là tuyệt vời ...

EDIT: phương pháp trên không làm hài lòng tôi không chỉ vì nó doesn 't nhìn tốt đẹp nhưng chủ yếu là vì tôi không thể giả định một mã của quá trình đang chạy sẽ quan tâm để cập nhật số của tôi. Tôi cần một cách để đảm bảo thực hiện mà không thay đổi mã của quá trình ...

+0

Đây không phải là vấn đề đối với C. Đây chính là lý do tại sao các ngôn ngữ khác được tạo dựa trên C, ví dụ: Mục tiêu-C, C++, C#, v.v. –

+0

Tôi biết, nhưng đó là những gì tôi phải làm ... vì vậy ... –

+4

Thực tế là mọi bản sao con trỏ phải được thiết kế không phải là "vấn đề với cách tiếp cận này": đó là vấn đề cơ bản của việc đếm tham chiếu. –

Trả lời

3

Một vấn đề sớm với tính tham khảo là nó là tương đối dễ dàng để đếm tham chiếu ban đầu bằng cách đặt mã trong một malloc tùy chỉnh/miễn phí thực hiện, nhưng nó là một chút khó khăn hơn để xác định nếu người nhận ban đầu vượt qua địa chỉ đó xung quanh với những người khác.

Vì C thiếu khả năng ghi đè toán tử gán (để tính số tham chiếu mới), về cơ bản, bạn còn lại với một số tùy chọn hạn chế. Người duy nhất có thể ghi đè lên bài tập là macrodef, vì nó có khả năng viết lại bài tập vào thứ gì đó mà inlines sự gia tăng của giá trị đếm tham chiếu.

Vì vậy, bạn cần phải "mở rộng" một macro mà trông giống như

a = b; 

vào

if (b is a pointer) { // this might be optional, if lookupReference does this work 
    struct ref_record* ref_r = lookupReference(b); 
    if (ref_r) { 
    ref_r->count++; 
} else { 
    // error 
    } 
} 
a = b; 

Bí quyết thực sẽ được viết một macro mà có thể xác định nhiệm vụ, và chèn mã sạch sẽ mà không đưa vào các tác dụng phụ không mong muốn khác. Vì macrodef không phải là một ngôn ngữ hoàn chỉnh, bạn có thể gặp phải các vấn đề mà khớp không thể thực hiện được.

(đùa về việc nhìn thấy móng tay nơi bạn học cách sử dụng búa có một điểm song song thú vị ở đây, ngoại trừ khi bạn chỉ có một cái búa, bạn nên học cách làm móng tay).

Các tùy chọn khác (có lẽ là lành mạnh hơn, có lẽ không) là theo dõi tất cả các giá trị địa chỉ được chỉ định bởi malloc, sau đó quét ngăn xếp và đống của chương trình cho các địa chỉ phù hợp. Nếu bạn khớp, bạn có thể đã tìm thấy một con trỏ hợp lệ hoặc bạn có thể đã tìm thấy một chuỗi có mã hóa may mắn; tuy nhiên, nếu bạn không phù hợp, bạn chắc chắn có thể giải phóng địa chỉ; miễn là họ không lưu trữ địa chỉ + bù trừ được tính từ địa chỉ ban đầu. (có lẽ bạn có thể macrodef để phát hiện các khoảng bù như vậy và thêm bù đắp như nhiều địa chỉ trong quá trình quét cho cùng một khối)

Cuối cùng, sẽ không có giải pháp dễ dàng nếu không xây dựng hệ thống tham chiếu, bạn trả lại các tham chiếu (các địa chỉ giả vờ); ẩn địa chỉ thực. Mặt trái của giải pháp như vậy là bạn phải sử dụng giao diện thư viện mỗi lần bạn muốn xử lý địa chỉ. Điều này bao gồm phần tử "tiếp theo" trong mảng, v.v. Không giống như C, nhưng gần giống với những gì Java làm với các tham chiếu của nó.

+0

cũng bạn nói 2 điều trái ngược, một là không có cách nào để ghi đè nhiệm vụ thứ hai mà nó có thể được thực hiện bởi macrodef ... vậy? –

+0

Chúng không hoàn toàn trái ngược nhau. Ghi đè là thuật ngữ kỹ thuật có nghĩa là "triển khai lại chức năng chuẩn với triển khai không chuẩn", trong khi macrodef là hệ thống phụ mở rộng văn bản sẽ không triển khai lại nhiệm vụ, nhưng bạn có thể cắt và dán mã nếu bạn thấy "đối sánh". Sau đó, bạn có thể xem liệu trước tiên bạn có thể viết một trận đấu chất lượng cao và sau đó "cắt và dán" trong mã "tăng số lượng tham chiếu" hay không. Có thể trong lý thuyết, nhưng macrodef quá hạn chế một ngôn ngữ mà nó có thể thực sự là không thể do các hạn chế macrodef. –

+1

Tìm kiếm số lượng tham chiếu trong bảng băm không phải là cách mọi người thực hiện. Cách đúng là bao gồm số đếm trong cấu trúc/bộ đệm. – asveikau

0

Tôi không nghĩ bạn có thể tự động thực hiện mà không có trình phá hủy/nhà xây dựng có thể ghi đè. Bạn có thể nhìn vào HDF5 ref đếm nhưng những yêu cầu cuộc gọi rõ ràng trong C:

http://www.hdfgroup.org/HDF5/doc/RM/RM_H5I.html

+0

Nhưng tại sao chính xác bạn đề nghị xem HDF5? – hmijail

1

Semi-nghiêm túc trả lời

#include "Python.h" 

Python có một người quản lý tài liệu tham khảo bộ nhớ đếm tuyệt vời. Nếu tôi đã phải làm điều này cho thực tế trong mã sản xuất, không phải bài tập về nhà, tôi muốn xem xét nhúng hệ thống đối tượng python trong chương trình C của tôi mà sau đó sẽ làm cho chương trình C của tôi scriptable trong python quá. Xem the Python C API documentation nếu bạn quan tâm!

+0

như tôi đã nói, các ngôn ngữ khác không liên quan để thảo luận của chúng tôi ... –

+8

Câu trả lời này đề cập đến API C C, là một tài nguyên thú vị liên quan đến câu hỏi này kể từ khi API bao gồm các tham chiếu tính C "đối tượng". – olovb

2

như vậy một hệ thống trong C đòi hỏi một số kỷ luật trên một phần của các lập trình viên nhưng ...

Bạn cần phải suy nghĩ về quyền sở hữu. Tất cả mọi thứ chứa tham chiếu đều là chủ sở hữu và phải theo dõi các đối tượng mà nó chứa tham chiếu, ví dụ: thông qua danh sách. Khi một điều đang nắm giữ tham chiếu bị phá hủy, nó phải lặp lại danh sách các đối tượng được giới thiệu của nó và giảm các bộ đếm tham chiếu của chúng và nếu chúng không phá hủy chúng lần lượt.

Các chức năng cũng là chủ sở hữu và nên theo dõi các đối tượng được tham chiếu, ví dụ: bằng cách thiết lập một danh sách ở đầu hàm và lặp lại nó khi trở về. Vì vậy, bạn cần phải xác định trong đó tình huống đối tượng cần được chuyển giao hoặc chia sẻ với chủ sở hữu mới và bọc các tình huống tương ứng trong macro/chức năng thêm hoặc loại bỏ các đối tượng sở hữu để sở hữu danh sách đối tượng tham chiếu (và điều chỉnh bộ đếm tham chiếu) theo đó).

Cuối cùng, bạn cần xử lý các tham chiếu vòng tròn bằng cách nào đó bằng cách kiểm tra các đối tượng không còn truy cập được từ các đối tượng/con trỏ trên ngăn xếp. Điều đó có thể được thực hiện với một số cơ chế thu thập rác và đánh dấu rác.

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