2013-08-13 1 views
1

У меня есть два образца кода:
во-первых, работает правильно:capset терпит неудачу с указателем на структуру

#include <sys/capability.h> 
#include <unistd.h> 
#include <cstdio> 

int main() 
{ 
    __user_cap_header_struct *hdr = new __user_cap_header_struct; 
    __user_cap_data_struct *data = new __user_cap_data_struct; 
    hdr->pid = getpid(); 
    hdr->version = _LINUX_CAPABILITY_VERSION; 
    data->effective &= ~CAP_TO_MASK(CAP_IPC_LOCK); 
    data->permitted &= ~CAP_TO_MASK(CAP_IPC_LOCK); 
    data->inheritable = 0; 
    if (capset(hdr, data) < 0) 
     printf("capset failed: %m"); 

    return 0 
} 

Во-вторых, fail: Operation not permitted:

#include <sys/capability.h> 
#include <unistd.h> 
#include <cstdio> 

int main() 
{ 
    struct __user_cap_header_struct hdr; 
    hdr.pid = getpid(); 
    hdr.version = _LINUX_CAPABILITY_VERSION; 
    struct __user_cap_data_struct data; 
    data.effective &= ~CAP_TO_MASK(CAP_IPC_LOCK);  
    data.permitted &= ~CAP_TO_MASK(CAP_IPC_LOCK); 
    if(capset(&hdr, &data)) 
     printf("capset failed: %m"); 

    return 0; 
} 

Я думаю, что оба образца кода одинаковы.
Когда я запускаю первый, он выполняется правильно (использует указатель на struct).
Но второй сбой (используется экземпляр struct).
Я не знаю почему. Вы можете мне помочь?

ответ

5

Скорее всего, потому, что инициализация структур. При объявлении локальной переменной ее значение равно неопределенным, используя это значение, а затем приводит к неопределенное поведение.

То же самое относится к переменным локальной структуры. Значения полей члена просто не определены, поэтому, когда вы делаете это, например, data.effective &= ~CAP_TO_MASK(CAP_IPC_LOCK); вы используете неопределенное (и, казалось бы, случайное) значение для операции.

Перед использованием необходимо инициализировать структуру до знанного значения. Как

struct __user_cap_header_struct hdr = { 0 }; 

Вышеупомянутое установит все поля в структуре равными нулю.

При выделении с new (который является C++, а не C!), То для структур (или классов) без конструкторов по умолчанию все поля-члены по умолчанию построены, так и для целых полей это означает, что они обнуляются. Если вы выделили структуры в первом примере, используя malloc (так как это способ распределения памяти), то вы получите тот же результат, что и второй пример, так как выделенная память не будет инициализирована вообще.

+0

Право. Спасибо, Иоахим! – aviit

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

  • Нет связанных вопросов^_^