2016-05-10 4 views
0

У меня есть проект, использующий разделяемую память, и каждый раз я получаю от него цикл чтения, поэтому я хочу проверить, что он пуст. код для открытия разделяемой памяти с помощью:Как проверить, пуста ли разделяемая память?

key_t key; 
int shmid; 
if ((key = ftok("ex31.c", 'k')) == -1){ 
    perror("ftok"); 
    exit(1);} 
if ((shmid = shmget(key, 3, FLAGS)) == -1) { 
      perror("shmget"); 
      exit(1);} 
char* shmaddr; 
if(shmaddr=shmat(shmid,0,0) == (char*)-1){ 
    printf("error in attaching to the shared memory\n"); 
    exit(0);} 
if(shmaddr==NULL) /// THROWS EXCEPTION!! 

он дает мне ошибку:

segmentation fault (core dumped) 

..HELP?

+2

Просьба привести пример, который мы можем скомпилировать и попытаться получить тот же результат, что и вы. –

+0

#define FLAGS IPC_CREAT | 0644, может быть, эта часть кода помогает, кроме того, что больше ничего не показывать –

+0

Если у вас нет отладчика, printf() каждой строки, чтобы вы могли определить, какая команда (если таковая имеется) действительно вызвала ошибку seg. Прямо сейчас, это может быть в рамках любой из ваших функций. Вывод (core dumped), если он имеет память и регистры и другие свойства, такие как трассировка стека, также может действительно помочь. Если ошибка возникает в инструкции if, предварительно распечатайте shmaddr, чтобы узнать, действительно ли у вас есть доступ к ней, и это не мусор. –

ответ

2

Я предлагаю вам иметь быстрый взгляд на это полная программа и посмотреть, что происходит, когда вы запустите его дважды, первый с аргументом -1, а затем снова с аргументом 42:

#include <stdio.h> 
int main (int argc, char *argv[]) { 
    int i; 
    if (i = atoi (argv[1]) == -1) 
     printf (" WAS negative one: %d\n", i); 
    else 
     printf (" was NOT negative one: %d\n", i); 
    return 0; 
} 

стенограмма выглядит следующим образом:

pax> ./testprog -1 
    WAS negative one: 0 
pax> ./testprog 42 
    was NOT negative one: 1 

Вы можете видеть, что, несмотря на то, что определяет значение atoi правильно, i появляется не т o правильно установить после сравнения.

Если вы посмотрите на код, вы уже знаете (или скоро будет знать, как только вы закончите читать этот ответ), как решить эту проблему. Сравните свою непослушную линию с одним из других (и немного переформатировать, чтобы сделать это очевидно):

if ((shmid = shmget (key, 3, FLAGS)) == -1  ) { 
if (shmaddr = shmat (shmid, 0, 0 ) == (char*)-1) { 
//^        ^
// \_______extra parentheses_______/ 

Причина вторая линия не работает, как вы ожидаете, потому что == имеет более высокий приоритет, чем=. Это означает, что первая строка делает то, что вы хотите, но второй эффективно:

if (shmaddr = (shmat (shmid, 0, 0) == (char*)-1)) { 
// \   \________higher________________//
// \____________________lower________________/ 

Как вы можете видеть, что приоритет правило означает, что выражение shmat (shmid, 0, 0) == (char*)-1 оценивается первым, а затем результат, что (1 для true или 0 для false) присваивается shmaddr. Оба эти значения: очень вряд ли будут действительным адресом памяти, поэтому почти наверняка вызывает сбой при попытке разыменовать его (a).

Линия вы должны должны соответствовать формату двух других, со скобками вокруг задания, чтобы гарантировать, что это сделано в первую очередь:

if ((shmaddr = shmat (shmid, 0, 0)) == (char*)-1)) { 
//^       ^
// \__________add these_________/ 

(а) Случай 1 быть назначен, не имеет значения для вашего случая, так как это означает, что условие if оценивается как true, и ваша программа выйдет. Следовательно, только только путь к коду, который пытается разыменовать shmaddr, будет иметь значение 0.

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