【问题标题】:C shmat in function [closed]函数中的C shmat [关闭]
【发布时间】:2014-12-18 20:59:09
【问题描述】:

我想创建一个在 C 中创建和附加共享内存的函数。当我在 main 中执行此操作时,它工作正常,但是当我将相同的代码放入函数时,shmat 返回 NULL

int main() { 

    int data=0; 
    int* shm_data=NULL; 
    int shmid; 

    if ( ( shmid = shmget( SMKEY_data, sizeof(int), IPC_CREAT  | 0666 ) ) < 0) { 
        perror("Shmget Faild (shmid) "); 
        exit(3); 
    } 

    if ( (shm_data = shmat(shmid, 0, 0)) == (int *) - 1) { 
         perror("Shmat Faild (shm_data) "); 
         exit(4); 
    } 
    *shm_data = data; 

    printf("1: %d\n", *shm_data); 

    if ( fork() == 0 ) { 
        (*shm_data)++; 
    } 
    else { 
        int s; 
        wait(&s); 
        printf("2: %d\n", *shm_data); 
    } 
    return 0; 
} 

输出:

1:0
2:1

void doshm(int* shmid, int* shm_data, int* data) { 
    if ( ( (*shmid) = shmget( SMKEY_data, sizeof(int), IPC_CREAT  | 0666 ) ) < 0) { 
        perror("Shmget Faild (shmid) "); 
        exit(3); 
    } 

    if ( (shm_data = shmat( (*shmid), 0, 0)) == (int *) - 1) { 
         perror("Shmat Faild (shm_data) "); 
         exit(4); 
    } 
    *shm_data = *data; 
} 

int main() {
    int data=0; 
    int* shm_data=NULL; 
    int shmid; 

    doshm(&shmid, shm_data, &data); 

    printf("1: %d\n", *shm_data); 

    if ( fork() == 0 ) { 
        (*shm_data)++; 
    } 
    else { 
        int s; 
        wait(&s); 
        printf("2: %d\n", *shm_data); 
    } 
    return 0; 
} 

输出:

Segmentation fault (core dumped)

【问题讨论】:

  • 有趣。你能找出分段错误发生在哪里吗,例如通过使用 gdb?
  • 是的!在 printf 从函数返回时,因为 shm_data 为空!

标签: c posix shared-memory


【解决方案1】:

shm_data 被初始化为 NULL 并且永远不会重新分配,像这样通过引用 doshm 来传递它

doshm(&shmid, &shm_data, &data);

然后将doshm的签名改为

doshm(int* shmid, int** shm_data, int* data)

最后,从doshm 中删除这一行

*shm_data = *data

另外,在doshm 之后、printf 之前检查shm_data == NULL

【讨论】:

  • 成功了!谢谢!
【解决方案2】:

当你写作时

doshm(&shmid, shm_data, &data);

然后你在doshm 中更改shm_data 的值

if ( (shm_data = shmat(shmid, 0, 0)) == (int *) - 1) { ... }

那么此更改将对变量的本地副本进行操作,并且此更改不适用于位于main 范围内的版本,其中shm_data 仍将是NULL

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-17
    • 2016-09-20
    • 1970-01-01
    • 2022-06-15
    相关资源
    最近更新 更多