2012-05-27 31 views
5

Bunu saatlerce deneyimledim ve google'ı düşündüğüm her şeyi google, ama deliriyorum. e kadar sonraPaylaşılan bellek bölümünün içindeki işaretçiler

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

ben int * (bir Matrix) boyutlarını bilmiyorum kömürleşmesini *:

Ben bir yapı var. Ben ne zaman

, böyle paylaştı bellek oluşturmak:

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); 
} 

Sorun burada. Sonra, ctrl-> satır ve kolekslerine bir değer veriyorum ve tüm matrislere 0 atayım. Ancak bundan sonra char * ve bam, segmentation hatasına bir şey yazarım.

Programdan hata ayıklama, her iki işaretçinin, matın ve IDs_row öğesinin null olduğunu gördüm. Paylaşılan bellek segmentindeki doğru değerleri nasıl verebilirim?

Sadece bir deneme yapmak için char * işaretçisini kaldırmayı denedim ve ardından segmentasyon hatası hatası, söz konusu paylaşılan belleğe bağlı olan ve matris içindeki değerleri kontrol eden diğer programda (kontrol -> satırlar ve -> collumns başarılı oldu)

cevap

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

Bu sadece ctrl->mat veya ctrl->IDs_row için, ctrl pointer geçerli bellek atar.

Muhtemelen istiyorum: - bu işaretçiler sadece kendi değerlerine doldurulmuş sürecinde geçerli olacak tüm

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

Teşekkür ederiz! Her bir işaretçi için shmget yapmayı hiç düşünmemiştim. (Bunun nasıl çalıştığını anlayamıyorum bile, aynı çağrıyı yapıyor ancak "çevirmek" Artık, yapıda "collumns" içindeki ikinci tam sayı ile ilgili bir sorun var. Bir işlemde "1" yazdım ve diğer süreç 62045 ya da bunun gibi bir şey okuyor. Ben (ctrl) boyutlarını sizeof (erkek) ve 2 * sizeof (int) + sizeof (int *) + sizeof (char *) olarak değiştirmeyi denedim, ancak şans yok. – Knudow

+0

Üzgünüm, mesajı yolladım ve daha sonra düzenledim. Bana biraz daha yardım edebilir misin? Yapıdaki ikinci tam sayı ile şimdi bir sorunum var. – Knudow

+0

@ user1420534 Lütfen bu yeni sorunla ilgili yeni bir soru gönderin, alakalı görünmüyorlar. –

7

Birincisi, paylaşımlı bellek segmentlerinde mutlak işaretçileri koyarak korkunç terible fikri olduğunu. Paylaşılan bellek segmentleri, her işlemde aynı sanal adrese eklenmek üzere garanti edilmez. Tam tersine, sisteminnumaralı telefona shmaddr == NULL numaralı telefondan belirtildiği durumlarda sisteme nerede eklediğini eklerler. shmat() numaralı telefonu ararken aynı sanal adresi belirtebilirsiniz, ancak tüm katılımcı işlemlerinde başka hiçbir şeyin bu bellek bölgesinde eşlenmediğinden emin olmak size kalmıştır. Bu taşınabilir bir şekilde yapmak zordur. En çok ne yapmak isterseniz:

1) Hem mem yapısını hem de iki veri dizisini barındıran büyük bir paylaşılan bellek segmentini ayırın. Sonra mutlak işaretçiler değil, bellek bloğunun başlangıcına göre işaretçiler koymanız ve sonra da kullanıma göre ayarlamanız gerekir.

2) üç farklı paylaşılan bellek kesimlerini tahsis ama bunun yerine işaretçileri koyma shmget() tarafından iade olarak, paylaşılan bellek kimlikleri koydu: Eğer matris veya kimlikler dizisine erişmek için ihtiyaç

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

sadece ilgili alanda saklanan paylaşımlı hafızaya iliştirin. izleyen sonraki çağrılarda aynı KEY kullanarak, KEY == IPC_PRIVATE sürece beklenen sonucu üretmeyecek olmasına dikkat edin. Diğer iki bellek bloğu için tanımlayıcı (mem türünde) ve IPC_PRIVATE için paylaşılan bellek bloğu için sabit anahtar değerini kullanmak en iyisidir, aksi halde üç çağrı aynı aynı paylaşımlı bellek bloğunu döndürür - ilk olan onu yaratın ve sonraki ikisi de bu anahtarın bulunduğu bir bloktan beri kimliğini döndürecektir.

İlgili konular