Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Shared memory pointer segmentation fault

Hey am trying to create a shared object between 2 processes.and trying to read and change the values from each one of them.This s my simple struct.

EDIT: I added a constructor to my struct.

struct shared{
    shared(){
        value = 10;
        name = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
    }
    int value;
    string name;
};

I tried both to call shmat() before and after calling fork() but nothing change it still give segmentation fault.

EDIT:And added a check after the shmat() to see if it failed.

#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <iostream>
#include <sys/shm.h>
#include <string.h>

using namespace std;

struct shared{
    shared(){
        value = 10;
        name = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
    }
    int value;
    string name;
};

int main(){
    int shm_id = shmget(IPC_PRIVATE,sizeof(shared),0);

    if(shm_id == -1){
        cout<<"shmget() failed "<<endl;
        return -1;
    }
    pid_t pid = fork();
    if(pid == -1){
        cout<<"fork() failed "<<endl;
        return -2;
    }

    shared* sharedPtr = (shared*)shmat(shm_id,0,0);


    if(sharedPtr == 0){
        cout<<"shmat() failed "<<endl;
    }

    cout<<"Setting up the object: "<<endl;
    sharedPtr->value = 5;
    sharedPtr->name = "aaaaaa: ";

    if(pid == 0){       //Child process

        cout<<"Child process: "<<endl;
        sharedPtr->value = 10;
        sharedPtr->name  = "bbbbbbb: ";
        cout<<"Changed the object "<<endl;
        return 0;
    }
    if(pid != 0){ //Parent process
        sleep(1);
        cout<<"Parent process: "<<endl;
        cout<< sharedPtr->name << sharedPtr->value<<endl;

    }

    return 0;
}

But I still get a segmentation fault.

like image 291
Sero Mirzakhanyan Avatar asked Jan 08 '18 07:01

Sero Mirzakhanyan


People also ask

How can I fix segmentation fault?

It can be resolved by having a base condition to return from the recursive function. A pointer must point to valid memory before accessing it.

What causes segmentation fault with pointers?

A segmentation fault usually occurs when you try to access data via pointers for which no memory has been allocated. It is thus good practice to initialize pointers with the value NULL, and set it back to NULL after the memory has been released.

Can out of memory cause segmentation fault?

Overview. A segmentation fault (aka segfault) is a common condition that causes programs to crash; they are often associated with a file named core . Segfaults are caused by a program trying to read or write an illegal memory location.

What are three kinds of pointers that can cause a segmentation fault?

Dereferencing or assigning to an uninitialized pointer (wild pointer, which points to a random memory address) Dereferencing or assigning to a freed pointer (dangling pointer, which points to memory that has been freed/deallocated/deleted) A buffer overflow. A stack overflow.


1 Answers

The check for validity of the pointer (if(sharedPtr == 0){) occurs after the pointer has already been dereferenced in sharedPtr->value. So you could be getting this behaviour because you are dereferencing a null pointer. Put this check before you use the pointer.

Furthermore, you can't use shared memory like that. You are getting a statically sized shared memory pointer that represents memory equivalent to an uninitialized string and int, think about this. You essentially have this:

int : size -> 4 bytes
empty string : size -> 32 bytes

(From here, system dependent). Then when you do this (shared*)shmat(shm_id,0,0) and this sharedPtr->name = "aaaaaa: ", the string you have created in this struct never had its constructor called and therefore was not created correctly. When you do the operator= you are attempting to use a function that doesn't exist anywhere because the object you are calling it on wasn't constructed correctly. If you are using raw shared memory, you will need to be very careful about how you use it and how much size you will take up. You could also consider using a memory controller to help you, like boost::interprocess.

like image 153
Fantastic Mr Fox Avatar answered Sep 19 '22 01:09

Fantastic Mr Fox