Search code examples
cshared-memory

Why is dynamically allocated memory in a shared memory reset to the initial value it was initialised to


I have the following code that initializes a shared memory, with the starting values:

void initializeSharedMemory(SharedMemoryPtr sharedMemoryPtr, int size) {
    sharedMemoryPtr->bestSolutionDistance = 1e9; 
    sharedMemoryPtr->BestSolutionFoundByProcess = -1; 
    sharedMemoryPtr->BestSolutionFoundInIterations = -1;
    sharedMemoryPtr->solutionVector = createVector(size);
    sharedMemoryPtr->dataTest  = calloc(size,sizeof (int));
    initializeVector(sharedMemoryPtr->solutionVector, sharedMemoryPtr->dataTest);
}

i have a sharedMemory struct:

typedef struct{
    int bestSolutionDistance;
    int BestSolutionFoundByProcess;
    int BestSolutionFoundInIterations;
    VectorPtr solutionVector;
} SharedMemory;

And a typedef for SharedMemoryPtr

typedef SharedMemory *SharedMemoryPtr;

on my main.c i create the shared memory, map it and initialize it:

size_t sharedMemorySize = sizeof(SharedMemory);
int shm_fd = createOrOpenSharedMemory(SHM_NAME, sharedMemorySize);
if (shm_fd == -1){
    fprintf(stderr,"Error Opening shared memory!\n");
    return EXIT_FAILURE;
}

sharedMemoryAllocatedPtr = mapSharedMemory(shm_fd,sharedMemorySize);
if (sharedMemoryAllocatedPtr == NULL){
    fprintf(stderr,"Error Mapping shared memory!\n");
    return EXIT_FAILURE;
}

initializeSharedMemory(sharedMemoryAllocatedPtr,distanceMatrix->size);

problem is on my child processes i can update the shared memory to update the best solution found, it updates without a problem, but when i wanna print the final state of the shared memory after all processes exit, the values go back to the initial values defined ininitializeSharedMemory:

=========================Arguments=======================================
Problem file: ex5.txt , numProcesses: 1, maxIterations: 1000000000, maxDuration: 5s
Distance Matrix { 
0 23 10 4 1 
23 0 9 5 4 
10 9 0 8 2 
4 5 8 0 11 
1 4 2 11 0 
}
=========================================================================
Vector was this before updating:Vector { 0 0 0 0 0 }
Vector is now this after:Vector { 3 4 2 1 0 }
Vector was this before updating:Vector { 3 4 2 1 0 }
Vector is now this after:Vector { 1 0 3 2 4 }
Vector was this before updating:Vector { 1 0 3 2 4 }
Vector is now this after:Vector { 0 4 2 1 3 }
==========================Done===========================================
Best Solution:
Vector { 0 0 0 0 0 }
Found at iteration: 1290817 by PID: 5295
Distance: 21
=========================================================================

Solution

  • Your struct is allocated in shared memory, but sharedMemoryPtr->dataTest (and possibly sharedMemoryPtr->solutionVector, but you failed to provide the definition of createVector, so who knows?) is allocated on the local process heap via calloc; it's not in shared memory. The parent process, not having done anything since creating it zeroed, only sees it as zeroes after, because changes the other processes make to their local heap are local to those processes.

    Odds are, the code is "working", rather than crashing, because you're on an OS, and using APIs, to perform fork-based parallelism, so the calloc-ed memory remains at the same address in the child processes; with anything other than fork-based parallelism, ASLR would likely relocate the heap and the attempt to dereference an address calloc-ed in the parent process from any child process would die trying to read unallocated memory. With fork, it just performs a copy-on-write in the child process, so the child can use the memory just fine, but the changes are purely local to the child, with the parent retaining its pristine zeroed memory.