日期:2014-05-16  浏览次数:20731 次

Unix 共享内存core问题
这两天再学习共享内存的东西,写了个小例子,但是发现连接共享内存返回的地址赋值给char *writemsg,然后断开共享内存连接,使 writemsg=NULL;再进行writemsg的赋值时,程序会core掉
不明白是啥情况,不是置为NULL就可以使用了么??再第二个重连后再赋值就不会core
具体看下面代码注释的地方

int main()
{
    int shm_id;
    key_t key = 0xb0000001;
    char *writemsg ;
    char *readmsg ;

    printf("key is:%x\n",key);
    if((shm_id = shmget(key,32,0666|IPC_CREAT))==-1)
    {
        printf("connet 0xb0000001 error\n");
    }else{
        printf("connet 0xb0000001 success\n");
        printf("shm_id is:%d\n",shm_id);
    }

    writemsg = (char *) shmat(shm_id,0,0);
    strcpy(writemsg,"this is what I want to write to the shm");
    shmdt((void *)writemsg);

    writemsg = NULL;
//这里memcpy()会core掉
    memcpy(writemsg,"want to write to the shm",sizeof(writemsg));

    if((readmsg = (char *) shmat(shm_id,0,0))<0)
    {
        printf("连接共享内存失败\n");
    }else{
        printf("开始显示内存数据\n");
        printf("%s\n",readmsg);
    }
    //这里memcpy()不会core
    //memcpy(writemsg,"want to write to the shm",sizeof(writemsg));
    shmctl(shm_id, IPC_RMID, NULL);


    return 0;
------解决方案--------------------
writemsg = NULL;
这句让writemsg成为了空指针,没有分配任何的空间,memcpy对writemsg赋值一定会segment fault.

我不相信第二个memcpy对writemsg赋值不会core.
------解决方案--------------------
因为shmat第二个参数是0,系统选择可用的attatch的地址

第一次shmdt之后,writemsg指向的是一个无效的地址,memcpy自然会core.

再次shmat之后,系统还是attatch到了原来的地址(系统在进程地址空间中寻找第一个可用的地址), 相当于这时writemsg和readmsg指向了同一块地方,你可以打出来看一下.所以memcpy就不会core了.