Victor.Bbb
Victor.Bbb

Reputation: 23

Segmentation Fault occurs after using global variable in several function

I'm currently programming my Bachelor Project what consists an RFB-Client and a Shared Memory. The initialisation of the RFB-Client is done, the Shared Memory is created. My teacher told me to decouple the code and I wrote several functions and used a global variable for the shared memory.

But now a segmentation fault occurs while trying to read the content of the global variable. I debugged the code and found out: The content of the global variabel "my_shm" is always "0x00" :-/ Could you please help me?

These are the portions of code where the problem occurs: (I know, this is a long code, but sending just parts of it would be useless...)

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;

}

--> everywhere the variable "my_shm" is used: the content is: 0x00...

Upvotes: 0

Views: 2941

Answers (1)

Some programmer dude
Some programmer dude

Reputation: 409176

This seems to be a very common problem here on stackoverflow.com today, and the problem is that you pass arguments to function by value and not by reference.

What that means is that when you pass an argument to a function, its value is copied, and the function only work on the copy locally inside the function. As you should know, modifying a copy will of course not modify the original.

C does not have pass by reference, but it can be emulated by using pointers. In your case, since you have a pointer you need to pass a pointer to the pointer using the address-of operator, like

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

You of course need to modify the function to actually accept a pointer to the pointer:

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

And of course use the dereference operator * when using the variable:

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

Upvotes: 2

Related Questions