Ошибка записи в сегментированную память
Все, что я хочу сделать, это просто написать "эй" в моей общей памяти, но это бросается в эту строку. очень простой код следующим образом:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
#define SHM_SIZE 1024
#define FLAGS IPC_CREAT | 0644
int main(){
key_t key;
int shmid;
if ((key = ftok("ex31.c", 'k')) == -1){
exit(1);}
if ((shmid = shmget(key, SHM_SIZE, FLAGS)) == -1) {
exit(1);}
char* shmaddr;
if( shmaddr=shmat(shmid,0,0) == (char*)-1){ //WRONG ARGUMENTS ??
exit(0); }
printf("opened shared memory\n"); //gets here
strcpy(shmaddr, "hey"); //GETS THROWN HERE
printf("after writing to memory\n"); //never get here
ошибка, которую дает мне отладчик:
Программа получила сигнал SIGSEGV, Ошибка сегментации. 0x0000000000401966 в основном (argc=1, argv=0x7fffffffe068) в../ex31.c:449 449 strcpy(shmaddr, "hey"); // ПОЛУЧИВАЕТСЯ ЗДЕСЬ
1 ответ
Проблема в приоритете операторов. В соответствии
shmaddr=shmat(shmid,0,0) == (char*)-1)
Тогда одинарный -
оператор и оператор приведения имеют наивысший приоритет, затем ==
, с последующим =
который имеет самый низкий приоритет. Таким образом, ваш код оказывается равным
shmaddr=(shmat(shmid,0,0) == (char*)-1))
это ерунда.
Задание внутри условий - очень плохая практика программирования. Каждый полуприличный компилятор выдаст вам предупреждение, если вы попробуете это. Помимо проблем с приоритетом операторов, легко перепутать = и ==. Кроме того, оператор = вводит побочный эффект в выражение, поэтому смешивание его с другими операторами может привести к неопределенному поведению. И, пожалуй, самое главное, использование условий = inside обычно значительно снижает читабельность кода.
Ваш код должен быть написан как:
shmaddr = shmat(shmid,0,0);
if(chmaddr == (char*)-1){
Важно понимать, что вы ничего не получите, объединив эти 2 строки в 1. Сгенерированный машинный код будет идентичен, за исключением отсутствия ошибок в вышеприведенной версии.