c - 在多个函数中使用全局变量后发生段错误

标签 c linux shared-memory

我目前正在编写我的学士项目,该项目由一个 RFB 客户端和一个共享内存组成。 RFB 客户端的初始化已完成,共享内存已创建。我的老师告诉我解耦代码,我写了几个函数并为共享内存使用了一个全局变量。

但是现在在尝试读取全局变量的内容时发生了段错误。我调试了代码并发现:全局变量“my_shm”的内容始终是“0x00”:-/ 你能帮帮我吗?

这些是出现问题的代码部分: (我知道,这是一个很长的代码,但是只发送其中的一部分是没有用的......)

char *my_shm; --> //global variable

int SHM_init (int shmid, char* shm, key_t key, long int size) {


    /* Create a new (System V) shared memory segment of the specified size */
    shmid = shmget(key, SHM_SIZE, IPC_CREAT|0777);
    /* Check if SHM creation was successful */
    if (shmid < 0) {
        /* DBG: Debug message to show which point of the program has been passed */
        DBG_PRINT("C\n");

        /* Check if creation failed because of already existing SHM */
        if (EEXIST == errno) {
            /* DBG: Debug message to show which point of the program has been passed */
            DBG_PRINT("CC\n");
            /* Delete already existing SHM with shmctl */
            shmctl(shmid, IPC_RMID, NULL);
        } else {
            /* DBG: Debug message to show which point of the program has been passed */
            DBG_PRINT("CCC\n");
        }

        /* Creation and initialization of SHM failed */
        return -1;
    }
    /* Attach the SHM data pointer to the previously created SHM segment */
    shm = shmat(shmid, NULL, 0);

    if(shm == (char *) -1) {
        /* Attaching failed */
        return -1;
    }
    DBG_PRINT("Shared Memory Initialization successful\n");
    /* Creation and initialization of shared memory was successful */
    return 0;
}

void RFB_update(rfbClient* client) {    

    DBG_PRINT("RFB_update called\n");
    int i,j;

    rfbPixelFormat* pformat=&client->format;

    DBG_PRINT("A\n");

    /*bytesPerPix: variable which stores Bytes per Pixel*/
    int bytesPerPix = pformat->bitsPerPixel/8;

    DBG_PRINT("B\n");

    /*row= width of frame*bytes per Pixel*/
    int row=client->width*bytesPerPix;

        DBG_PRINT("C\n");

    char byte_to_write;

    //as long as j is smaller than 128*(width*bytesPerPix)
    for(j=0;j<client->height*row;j+=row) {
        //as long as i is smaller than 128 * bytesPerPix
        for(i=0;i<client->width*bytesPerPix;i+=bytesPerPix) {      
            /*frameBuff: Pointer on FrameBuffer*/        
         unsigned char* frameBuff = client->frameBuffer+j+i;  
            unsigned int v;         

           if(bytesPerPix==4)
                v=(unsigned int*)frameBuff;

            byte_to_write = ((v>>pformat->redShift)*256/(pformat->redMax+1));
            SHM_write_byte(my_shm,byte_to_write);

            byte_to_write = ((v>>pformat->greenShift)*256/(pformat->greenMax+1));
            SHM_write_byte(my_shm,byte_to_write);

            byte_to_write = ((v>>pformat->blueShift)*256/(pformat->blueMax+1));
            SHM_write_byte(my_shm,byte_to_write);


        }
    }

    DBG_PRINT("RFB_update successful, Shared Memory is filled\n");  
}

int SHM_write_byte (char** shm, char byte) {


    /*Check if pointer to SHM is valid */
    if (shm == (char **) -1) {
        /* Pointer is invalid */
        return -1;
    }
    shm = byte;
    shm++;

    return 0;
}

int main (int argc, char *argv[]) {

    if (SHM_init(shmid, my_shm, SHM_KEY, SHM_SIZE) != 0) {
        DBG_PRINT("Shared Memory initialized\n");
        /* Couldn't initialize SHM,initializing failed */
        return -1;
    }
    /* Initialize RFB Client         */
    if (RFB_client_init(rfb_client, (FinishedFrameBufferUpdateProc)RFB_update) != 0) {
        DBG_PRINT("Couldn't initialize client\n");
        /* Couldn't initialize Client,initializing failed */
        return -1;

}

--> 到处都使用变量“my_shm”:内容是:0x00 ...

最佳答案

这似乎是今天 stackoverflow.com 上的一个非常普遍的问题,问题是您将参数传递给函数按值而不是按引用

这意味着当您将参数传递给函数时,它的值会被复制,并且该函数仅在函数内部的本地副本上起作用。如您所知,修改副本当然不会修改原件。

C没有引用传递,但是可以用指针来模拟。在你的例子中,因为你有一个指针,你需要使用地址运算符将指针传递给指针,比如

SHM_init(shmid, &my_shm, SHM_KEY, SHM_SIZE)
//              ^
//              |
// Note ampersand (address-of operator) here

您当然需要修改函数以实际接受指向指针的指针:

int SHM_init (int shmid, char** shm, key_t key, long int size)

当然在使用变量时使用解引用运算符*:

*shm = shmat(shmid, NULL, 0);

关于c - 在多个函数中使用全局变量后发生段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34399441/

相关文章:

c - 数组与 malloc?

c - IPC - Linux 中的共享编程程序

C# 共享内存 - CPU 缓存的风险(非 volatile 读取)?

linux - ftp 为发送的每个文件创建一个日志

c - Linux 内核中的 stdlib.h 替代方案?

c++ - 观察 QSharedMemory 的变化

c - 未处理的异常 (C)

c - 限制 C 中的库链接

c - 获取C中文件的完整路径

python - 在linux中,如何使用python检查外部程序是否正在运行?