Я предлагаю вам иметь быстрый взгляд на это полная программа и посмотреть, что происходит, когда вы запустите его дважды, первый с аргументом -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.
Просьба привести пример, который мы можем скомпилировать и попытаться получить тот же результат, что и вы. –
#define FLAGS IPC_CREAT | 0644, может быть, эта часть кода помогает, кроме того, что больше ничего не показывать –
Если у вас нет отладчика, printf() каждой строки, чтобы вы могли определить, какая команда (если таковая имеется) действительно вызвала ошибку seg. Прямо сейчас, это может быть в рамках любой из ваших функций. Вывод (core dumped), если он имеет память и регистры и другие свойства, такие как трассировка стека, также может действительно помочь. Если ошибка возникает в инструкции if, предварительно распечатайте shmaddr, чтобы узнать, действительно ли у вас есть доступ к ней, и это не мусор. –