2016-12-08 5 views
0

У меня есть этот код:shmctl выбрасывает «не может выделить память» в C

#define SHMSIZE 8388606 
int main() 
{ 
    int shmid; 
    void *shmPtr; 
    char *shm; 
    if ((shmid = shmget(IPC_PRIVATE, sizeof(char) * SHMSIZE , IPC_CREAT |  0666)) < 0) { 
     perror("shmget"); 
     exit(1); 
    } 

    if ((shmPtr = shmat(shmid, NULL, 0)) == (char *) -1) { 
     perror("shmat"); 
     exit(1); 
    } 
    shm = (char *)shmPtr; 
    strncpy(shm, "0\n", 2); 

    struct shmid_ds shmid_ds; 
    int rtrn = shmctl(shmid, SHM_LOCK, &shmid_ds); 
    if(rtrn < 0) { 
     perror("shmctl"); 
     exit(1); 
    } 
    else { 
     printf("Nailed it\n"); 
    } 
    return 0; 
} 

Бег, я получаю ошибку:

shmctl: Cannot allocate memory

Определение меньшее значение для SHMSIZE исправляет ошибку, но что Мне показалось странным, что эта ошибка возникает в части «shmctl». Мои рассуждения говорят мне, что эта ошибка должна быть выбрана в части «shmget».

Как этот код успешно работает через вызов shmget()? Я пропустил что-то важное?

+1

Я рекомендую вам [читать shmctl' страницу 'вручную] (HTTP: // man7 .org/linux/man-pages/man2/shmctl.2.html), и что он говорит об ошибке «ENOMEM». –

+0

'struct shmid_ds shmid_ds;' не инициализируется. – wildplasser

ответ

0

Прочитайте это, может помочь вам решить вашу проблему:

The caller can prevent or allow swapping of a shared memory segment 
    with the following cmd values: 

    SHM_LOCK (Linux-specific) 
      Prevent swapping of the shared memory segment. The caller 
      must fault in any pages that are required to be present 
      after locking is enabled. If a segment has been locked, 
      then the (nonstandard) SHM_LOCKED flag of the shm_perm.mode 
      field in the associated data structure retrieved by 
      IPC_STAT will be set. 

    SHM_UNLOCK (Linux-specific) 
      Unlock the segment, allowing it to be swapped out. 

    In kernels before 2.6.10, only a privileged process could employ 
    SHM_LOCK and SHM_UNLOCK. Since kernel 2.6.10, an unprivileged 
    process can employ these operations if its effective UID matches the 
    owner or creator UID of the segment, and (for SHM_LOCK) the amount of 
    memory to be locked falls within the RLIMIT_MEMLOCK resource limit 
    (see setrlimit(2)). 

Попробуйте это:

int rtrn = shmctl(shmid, IPC_STAT, &shmid_ds);

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