2013-02-23 5 views
0

.... привет, ребята, я всегда получаю сообщение «Ошибка сегментации» при запуске моего кода. что я знаю, что эта ошибка возникает, когда есть проблема с записью в файл (я думаю, что это касается разделяемой памяти), я знаю, что ошибка исходит из цикла for, я пробовал все, чтобы решить эту ошибку, но не удалось (я даже удалил цикл for и набрал только * s = 'A'). Любая помощь, пожалуйста.Неполадка записи в сегмент разделяемой памяти

#include <stdio.h> 
#include <sys/types.h> 
#include <sys/ipc.h> 
#include <sys/shm.h> 
#include <stdlib.h> 

main() 
{ 
    //Shared memory parameters 
    int shmid ; 
    int shmsize = 14; 
    key_t key = 2121; 
    char *shm, *s; 
    //Create SMS 
    if ((shmid = shmget (key , shmsize, 0666 | IPC_CREAT)) == -1) { 
     perror ("Error in Creating the SMS"); 
     abort(); 
    } 
    //Attatching the sms to the address space 
    if (shm = shmat(shmid , NULL , 0) == (char *)-1) { /*<<<< 23 */ 
     perror ("Error in attatching the SMS"); 
     abort(); 
    } 
    int i ; 
    s = shm; 
    for(i = 0 ; i <= 63 ; i++) 
     *s++ = (char)i; 
     *s = NULL; /*<<<< 33 what's the problem */ 
} 

Также я получаю предупреждение в обеих 23 и 33

ответ

1

Вы должны слушать составитель предупреждение (и вы должны получить предупреждение для линии 7, один с main на нем, а также - если вы не 't, то вы должны добавить -Wall в коммутаторы компилятора).

Так на линии 23 он говорит, что «делает указатель из целого числа без гипса» [1]:

if (shm = shmat(shmid , NULL , 0) == (char *)-1) 

Это потому, что ваша строка коды не делать то, что вы думаете, он должен делать. Если мы разделим его на отдельные строки, то это станет яснее, не так ли?

shm = shmat(shmid , NULL , 0) == (char *)-1; 
    if (shm) 

Итак, шм становится результат «возвращаемого значения shmat(...) == -1 который, будем надеяться равна нулю Тогда вы назначаете s к shm, что означает, что *s++ пытается записать адрес нуля -.., Которые, безусловно, должны дать сбой сегм .

Фикс, добавив скобки, чтобы сделать назначение произойдет первым, то сравнение (как в shmid = shmget несколько строк выше) - или разбить его, как это (мое предпочтительное решение):

shm = shmat(shmid , NULL , 0); 
    if (shm == (char *)-1) 

Эта линия:

    *s = NULL; //what's the problem 

неправильно, потому что вы пытаетесь присвоить NULL (который является (void *)0, и, таким образом, указатель) на значение char. Исправьте это, либо из этих двух линий:

*s = '\0'; 
*s = 0; 

В соответствии с комментарием ниже: Вы должны также позаботиться о размере вашей общей памяти, чтобы покрыть содержимое, которое необходимо сохранить. В настоящее время вы запрашиваете 14 байтов, а затем записываете 64. Это не подводит, но это только потому, что размер округляется до 4096 байт - важно не «лгать» ОС о том, что вы просите - даже если вы иногда уйти с ним ...

[1] Это всегда полезно, если вы разместите фактические предупреждающие сообщения, что позволит сэкономить мне необходимости компилировать код, чтобы найти предупреждения ...

+2

вы можете добавить в ваш ответ: размер shm равен 14, а цикл - 63 байта ... – Aubin

+0

Большое спасибо, я буду осторожен в следующий раз. –

Смежные вопросы