Hey all!
Long time reader, first time poster!

So I'm trying to communicated between two processes on a UNIX machine using shared memory. I believe everything in this program is working fine except for how I'm attempting to call the memory to check.

Basically the parent process writes to the shared memory and says "How are you my child?" and the child process checks the shared memory and if the question is there it writes an answer of "I am fine, thanks!" but my check isn't nearly correct.

The attempted code I used was if (("%s",shared_memory) == "How are you my child?") but that's not correct cause it's skipping the if statement and moving to the else. How can I properly check the shared memory?

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

#include <iostream>
#include <iomanip>
#include <string>
#include <fstream>
using namespace std;

int main()
{
    pid_t           pid;
	/* the identifier for the shared memory segment */
	int             segment_id;
	/* a pointer to the shared memory segment */
	char           *shared_memory;
	/* the size (in bytes) of the shared memory segment */
	const int       segment_size = 4096;

	/** allocate  a shared memory segment */
	segment_id = shmget(IPC_PRIVATE, segment_size, S_IRUSR | S_IWUSR);

	/** attach the shared memory segment */
	shared_memory = (char *) shmat(segment_id, NULL, 0);
	printf("shared memory segment %d attached at address %p\n", segment_id, shared_memory);

    sprintf(shared_memory, "How are you my child?");        //Parent writes

    printf("*Currently written in memory: %s*\n", shared_memory);

	/* fork another process */
	pid = fork();

	if (pid == 0)/* child process */
	{
        if (("%s",shared_memory) == "How are you my child?")
        {
		/** write a message to the shared memory segment   */
		sprintf(shared_memory, "I am fine thank you!");
        pause();
        }
	}
        else/* parent process */
        {
		usleep(100);//wait(NULL);
		/** now detach the shared memory segment */
            if (shmdt(shared_memory) == -1)
            {
			fprintf(stderr, "Unable to detach\n");
            }
		/** now remove the shared memory segment */
		shmctl(segment_id, IPC_RMID, NULL);
        }
        return 0;
}

Thanks a bunch!

Namaste,
-Ray-

Recommended Answers

All 4 Replies

As far as I know, this expression:

(("%s",shared_memory) == "How are you my child?")

will always evaluate to false. The first part "("%s",shared_memory)" will first evaluate "%s", which does nothing, and then evaluate shared_memory, which does nothing, and then return the value of "shared_memory" which is a pointer. Then, the equal comparison will compare the pointer "shared_memory" with the pointer to the literal string "How are you my child?". That will always be false because all pointers have a unique value, unless they point to the same place.

You need to use either:

if(std::string(shared_memory) == "How are you my child?")

Or, as I have seen from your code, you seem to prefer C to C++, so I'm guessing you would want to use the old "deprecated" C version:

if( strcmp(shared_memory,"How are you my child?") == 0 )

That should fix it.

Mike, first off, thank you very much! I tried your fix, choosing the C++ approach, and that cleaned up the statement however I guess it must not have been the only issue because the program is still skipping the if statement all together. Am I missing a concept of shared memory here?

My assumption was that if the parent wrote

sprintf(shared_memory, "How are you my child?");

and then forked you'd be able to see that in the shared memory as the child and respond to it but it's still skipping the if statement

Thanks again!

Namaste,
-Ray-

Well, I copied your program (with the modification) as follows:

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

#include <iostream>
#include <iomanip>
#include <string>
#include <fstream>
using namespace std;

int main()
{
    pid_t           pid;
	/* the identifier for the shared memory segment */
	int             segment_id;
	/* a pointer to the shared memory segment */
	char           *shared_memory;
	/* the size (in bytes) of the shared memory segment */
	const int       segment_size = 4096;

	/** allocate  a shared memory segment */
	segment_id = shmget(IPC_PRIVATE, segment_size, S_IRUSR | S_IWUSR);

	/** attach the shared memory segment */
	shared_memory = (char *) shmat(segment_id, NULL, 0);
	printf("shared memory segment %d attached at address %p\n", segment_id, shared_memory);

    sprintf(shared_memory, "How are you my child?");        //Parent writes

    printf("*Currently written in memory: %s*\n", shared_memory);

	/* fork another process */
	pid = fork();

	if (pid == 0)/* child process */
	{
        if (std::string(shared_memory) == "How are you my child?")
        {
		/** write a message to the shared memory segment   */
		sprintf(shared_memory, "I am fine thank you!");
                printf("Currently written in memory: %s\n", shared_memory);
        }
	}
        else/* parent process */
        {
		usleep(100);//wait(NULL);
		/** now detach the shared memory segment */
            if (shmdt(shared_memory) == -1)
            {
			fprintf(stderr, "Unable to detach\n");
            }
		/** now remove the shared memory segment */
		shmctl(segment_id, IPC_RMID, NULL);
        }
        return 0;
}

When I ran it on my computer (Linux Kubuntu 10.10, kernel 2.6.35.25, compiled with GCC version 4.6.0 (experimental)), it gave the following output, as expected:

shared memory segment 884739 attached at address 0x7f1812266000
*Currently written in memory: How are you my child?*
Currently written in memory: I am fine thank you!

So, I'm guessing the problem is not in the code.

Wow! Thanks Mike, I REALLY appreciate the in depth look. That's quite interesting because I'm running this on a SunOS 5.10 cluster and it just gives me an output that says
*Currently written in memory: How are you my child?*
Currently written in memory: How are you my child?

I'll take a look at what's going on there. I'd say this is solved now. On to pipes and sockets :-p Good fortune would be upon me if we meet again on this forum.

Namaste,
-Ray-

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.