简体   繁体   中英

Collatz Conjecture/shared memory C program

I am a very new programmer trying to understand this C program and get it to run. Currently, it compiles and runs but does absolutely nothing. Last night it was partially working, I was getting numbers but not the correct numbers. We were given a template that had everything (theoretically) except the Collatz section. I've looked over and over it and cannot see anything I've changed since last night. Can anyone help?

Edit: The Collatz conjecture says using this algorithm n = (n/2) if n is even; n = (3*n+1) if n is odd, continually applied, all positive integers will eventually reach 1. I did the same program without shared memory and it worked as written.
Thanks so much!!

#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/shm.h>
#include <sys/stat.h>

#define MAX_SEQUENCE 30

typedef struct {
    int size;
    char partial;
    long num[MAX_SEQUENCE];
} shared_data;

int main(int argc, char **argv)
{
    /* name of the shared memory segment */
    const char *name = "kmm27920";

    /* shared memory file descriptor */
    int shm_fd;
    int i, n;

    /* a pointer to the shared memory segment */
    shared_data* shared_memory;

    int pid;

    if (argc != 2) {
        fprintf(stderr, "Usage: a.out num\n");
        return 1;
    }

    n = atoi(argv[1]);

    /* create a shared memory object */
    shm_fd = shm_open(name, O_CREAT|O_RDWR, 0666);
    /* configure the size of the shared memory object */
    ftruncate(shm_fd, sizeof(shared_data));

    /* memory map the shared memory object */
    shared_memory = (shared_data *) mmap(0, sizeof(shared_data), PROT_WRITE, MAP_SHARED, shm_fd, 0);

    // create child process

    if ((pid = fork()) == -1) {
        perror("Failed to create child process");
        return 1;
    }

    if (pid > 0) {
        wait(NULL);
        for (i = 0; i < shared_memory->size; i++)
            printf("%d\n", shared_memory->num[i]);
    }
    else if (pid == 0) {
        // generate the collatz sequence and store the result in the shared memory
        // the first term is n
        
        while (n != 1) {
            if (n % 2 == 0){
                n = n / 2;
                shared_memory->num[i] = n;
                i++;
            }
            else if (n % 2 == 1) {
                n = 3 * n + 1;
                shared_memory->num[i] = n;
                i++;
            }
        }
                
        exit(0);
    }

    /* now remove the shared memory object */
    shm_unlink(name);
    return 0;
}

The reason it is called a "conjecture" is because to this day, no one has been able to prove that it does hold for any integer.

On the other hand, no one has found an integer that does not hit 1 at some point, or more specifically, a loop other than 1, 4, 2.

And many people have tried.

The reason this is important is because it is very likely the cause of failure for your program.

To be more specific, there are 2 reasons it fails:

First, you do not initialize i in the child process, the part where this loop is:

while(n!=1){
    ...
}

This means instead of starting to put results in shared_memory->num[0] you put them at an unknown index, which may be outside your array, causing memory corruption.

Second, the loop it self loops until n == 1 but depending on the input, this can take many more iterations than 30!

If I remember correctly, there is no way to calculate how many iterations a given number will require before reaching 1.

In your shared memory object you only have space for 30 numbers, meaning you must reach 1 in 30 steps or less.

But your program never checks that, so you could start writing to memory out of bounds of your array, which is "undefined behavior".

That means you program can crash, run forever, or print random wrong numbers, etc.

Finally, if by some miracle you do use a number that reaches 1 in less than 30 steps, and your i variable somehow starts with value 0, you still never initialize shared_memory->size which means your printing loop won't know when to stop, and will most likely print garbage.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM