2012-05-27 40 views
5

Tôi đã thử điều này hàng giờ đồng hồ, và google tất cả những điều tôi nghĩ đến, nhưng tôi sẽ phát điên.Con trỏ bên trong phân khúc bộ nhớ chia sẻ

Tôi có một struct:

typedef struct { 
    int rows; 
    int collumns; 
    int* mat; 
    char* IDs_row; 
} mem; 

Tôi không biết các kích thước của int * (một ma trận) và char * cho đến khi sau này.

Khi tôi làm, tôi có thể tạo bộ nhớ chia sẻ như thế này:

mem *ctrl; 
int size = (2 + ((i-1)*num_cons))*sizeof(int) + i*26*sizeof(char); //I have the real size now 
shmemid = shmget(KEY, size, IPC_CREAT | 0666); 
if (shmemid < 0) { 
    perror("Ha fallado la creacion de la memoria compartida."); 
    exit(1); 
} 
ctrl = (mem *)shmat(shmemid, 0, 0); 
if (ctrl <= (mem *)(0)) { 
    perror("Ha fallado el acceso a memoria compartida"); 
    exit(2); 
} 

Không có vấn đề ở đây. Sau đó, tôi đưa ra một giá trị cho ctrl-> hàng và collumns, và gán 0 cho tất cả các ma trận.

Nhưng sau đó, tôi viết một thứ gì đó trong lỗi * và bam phân đoạn.

Gỡ lỗi chương trình Tôi thấy rằng cả hai con trỏ, mat và IDs_row trong đó null. Làm thế nào để cung cấp cho họ các giá trị chính xác bên trong phân khúc bộ nhớ chia sẻ?

Tôi đã thử xóa con trỏ char *, chỉ để thử, sau đó lỗi lỗi phân đoạn nằm trong chương trình khác kết nối với bộ nhớ dùng chung và chỉ kiểm tra các giá trị bên trong ma trận (kiểm tra -> hàng và -> collumns là succesfull)

Trả lời

5
ctrl = (mem *)shmat(shmemid, 0, 0); 

này chỉ gán bộ nhớ có giá trị để con trỏ ctrl, không ctrl->mat hoặc ctrl->IDs_row.

Bạn có thể muốn:

mem *ctrl; 
shmemid = shmget(KEY, sizeof(ctrl), IPC_CREAT | 0666); 
//allocate memory for the structure 
ctrl = (mem *)shmat(shmemid, 0, 0); 

//allocate memory for the int* 
shmemid = shmget(KEY,((i-1)*num_cons))*sizeof(int), IPC_CREAT | 0666); 
ctrl->mat = (int*)shmat(shmemid, 0, 0); 

//allocate memory for the char* 
shmemid = shmget(KEY,i*26*sizeof(char), IPC_CREAT | 0666); 
ctrl->IDs_row = (char*)shmat(shmemid,0,0); 
+0

Cảm ơn bạn! Tôi đã không bao giờ nghĩ đến việc làm shmget cho mỗi con trỏ. (Tôi thậm chí không hiểu làm thế nào mà hoạt động, làm cuộc gọi tương tự nhưng "đúc" nó) Bây giờ có một vấn đề với số nguyên thứ hai trong cấu trúc, "collumns". Tôi đặt một "1" trong một quá trình, và quá trình khác đọc nó là 62045 hoặc một cái gì đó như thế. Tôi đã thử thay đổi sizeof (ctrl) để sizeof (nam) và 2 * sizeof (int) + sizeof (int *) + sizeof (char *), nhưng không may mắn. – Knudow

+0

Xin lỗi, tôi đã gửi tin nhắn và sau đó chỉnh sửa nó. Bạn có thể giúp tôi nhiều hơn một chút không? Tôi có một vấn đề bây giờ với số nguyên thứ hai trong cấu trúc. – Knudow

+0

@ user1420534 xin vui lòng gửi một câu hỏi mới với vấn đề mới này, họ không có vẻ liên quan. –

7

Trước hết, đặt tuyệt đối con trỏ trong các phân đoạn bộ nhớ chia sẻ là khủng khiếp terible ý tưởng - những con trỏ sẽ chỉ có giá trị trong quá trình đó điền vào các giá trị của họ. Các phân đoạn bộ nhớ chia sẻ là không được bảo đảm để đính kèm tại cùng một địa chỉ ảo trong mọi quá trình. Ngược lại - chúng đính kèm nơi hệ thống cho là có thể khi shmaddr == NULL được chỉ định khi gọi tới shmat(). Bạn có thể chỉ định cùng một địa chỉ ảo khi gọi shmat() nhưng tùy thuộc vào bạn để đảm bảo rằng không có gì khác được ánh xạ trên vùng bộ nhớ đó trong tất cả các quy trình tham gia. Điều này khó làm theo cách di động. Điều bạn muốn làm nhất là:

1) Phân bổ một bộ nhớ chia sẻ lớn chứa cả cấu trúc mem và hai mảng dữ liệu. Sau đó, bạn không nên đặt con trỏ tuyệt đối mà là con trỏ liên quan đến phần đầu của khối bộ nhớ và sau đó điều chỉnh theo cách sử dụng.

2) Phân bổ ba phân đoạn bộ nhớ chia sẻ khác nhau nhưng thay vì đưa con trỏ, đặt nhớ ID chia sẻ như trả về bởi shmget():

typedef struct { 
    int rows; 
    int collumns; 
    int mat_id; 
    int IDs_row_id; 
} mem; 

Khi bạn cần truy cập vào ma trận hoặc mảng ID chỉ cần đính kèm vào ID bộ nhớ chia sẻ được lưu trữ trong trường tương ứng.

Chú ý rằng việc sử dụng cùng một số KEY trong các lần gọi sau shmget() sẽ không tạo ra kết quả mong đợi trừ khi KEY == IPC_PRIVATE. Tốt nhất là sử dụng giá trị khóa cố định cho khối bộ nhớ chia sẻ với bộ mô tả (loại mem) và IPC_PRIVATE cho hai khối bộ nhớ khác nếu không, ba cuộc gọi sẽ thực sự trả lại khối bộ nhớ chia sẻ - bộ nhớ đầu tiên sẽ tạo ra nó và hai cái tiếp theo sẽ đơn giản trả về ID của nó vì một khối với khóa đó đã tồn tại.

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