LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 06-27-2005, 04:26 AM   #1
d1s4st3r
Member
 
Registered: May 2004
Location: Italy
Posts: 70

Rep: Reputation: 16
Problem with shared memory in C under Linux


Hi guys,
I'm writing a program using shared memory segments and I have the following problem:
first of all, I create a key, get a memory segment and then attach it (I will post only the necessary parts of code):
Code:
#define		MAX	5
#define		LEN	40

/* here the main() begins */

const key_t GENKEY = ftok(".", 'x');
char *smp1;
int shmid;

shmid = shmget(GENKEY, sizeof(char)*(MAX*LEN), IPC_CREAT|0655);

if (shmid==(-1))
{
    fprintf(stderr, "Error message.\n");
    exit(1);
}
else
{
    smp1 = (char *)shmat(shmid, 0, 0);
}
the program proceeds then by reading messages from a message queue, and for each message received it forks.
This is the following snippet:
Code:
pid = fork();

if (pid==(-1))
{
    fprintf(stderr, "Error message.\n");
    exit(1);
}
else if (pid==0) /* child process */
{
    char *answer = malloc(sizeof(char)*LEN);
    char *p;
    int objs = 0;
    int i;
    p = smp1; /* this points to the first character of the shared memory area (a string MAX*LEN chars long) ---> that's equal to "p = &smp1[0]" */

    for (i=0; i<MAX; i++)
    {
        if (p[i*LEN]=='v')
            objs++;
    }
    printf("Objects: %d\n", objs); /* the result is always right here */
				
    if (objs<MAX)
    {
        p = &smp1[objs*LEN]; /* here p points to a certain char of smp1 depending on objs that change at each cycle (it's like an offset) */

        /* here the string "answer" is filled with some data, then sent on
           the message queue. For now, everything works */

        strncpy(p, answer, LEN);
        p[0] = 'v';

     /* p = smp1(objs*LEN);            <--- THIS CODE DOESN'T WORK ALSO
        strncpy(p, answer, LEN);
        *(p) = 'v'; */

        printf("Objects (later): %d\n", objs); /* this is OK */
        printf("Entry: \"%s\" (%d; %d)\n", p, strlen(p), LEN); /* this is OK also */
        printf("SHMEM: \"%s\" (%d)\n", smp1, strlen(smp1)); /* HERE IS THE PROBLEM!!! smp1 seems to be *empty* and strlen returns 0 */
    }
    else
    {
        /* do something else */
    }

    shmdt(smp1);
    free(answer);
    exit(0);
}
else /* parent process */
{
    int w;
    w = waitpid(pid, 0, 0|WNOHANG);
}
I truly dont know why the shared memory segment (pointed by smp1 and p) results as empty when trying to print its contents. The two pointers point to the same area (expecially when objs=0 at the first iteration).
Could somebody please gimme a hand? I'm realy getting mad...

Many thank to everyone!
 
Old 06-28-2005, 04:17 PM   #2
Mara
Moderator
 
Registered: Feb 2002
Location: Grenoble
Distribution: Debian
Posts: 9,696

Rep: Reputation: 232Reputation: 232Reputation: 232
Re: Problem with shared memory in C under Linux

Quote:
Originally posted by d1s4st3r
Code:
     p = smp1(objs*LEN);            <--- THIS CODE DOESN'T WORK ALSO
Are you sure it's correct? It makes sense as p = smp1[objs*LEN], but I'm not sure what do you want to archieve with p = smp1(objs*LEN);
 
Old 06-28-2005, 06:22 PM   #3
aluser
Member
 
Registered: Mar 2004
Location: Massachusetts
Distribution: Debian
Posts: 557

Rep: Reputation: 43
I get this output:
Code:
Objects: 0
Objects (later): 0
Entry: "v" (1; 40)
SHMEM: "v" (1)
from the following:

Code:
#include <sys/shm.h>
#include <stdio.h>
#include <sys/wait.h>
#include <sys/types.h>

#define		MAX	5
#define		LEN	40

/* here the main() begins */

int main() {
	const key_t GENKEY = ftok(".", 'x');
	char *smp1;
	int shmid;
	pid_t pid;

	shmid = shmget(GENKEY, sizeof(char)*(MAX*LEN), IPC_CREAT|0655);

	if (shmid==(-1))
	{
	    fprintf(stderr, "Error message.\n");
	    exit(1);
	}
	else
	{
	    smp1 = (char *)shmat(shmid, 0, 0);
	}

	pid = fork();

	if (pid==(-1))
	{
	    fprintf(stderr, "Error message.\n");
	    exit(1);
	}
	else if (pid==0) /* child process */
	{
	    char *answer = malloc(sizeof(char)*LEN);
	    char *p;
	    int objs = 0;
	    int i;
	    p = smp1; /* this points to the first character of the shared memory area (a string MAX*LEN chars long) ---> that's equal to "p = &smp1[0]" */

	    for (i=0; i<MAX; i++)
	    {
		if (p[i*LEN]=='v')
		    objs++;
	    }
	    printf("Objects: %d\n", objs); /* the result is always right here */
					
	    if (objs<MAX)
	    {
		p = &smp1[objs*LEN]; /* here p points to a certain char of smp1 depending on objs that change at each cycle (it's like an offset) */

		/* here the string "answer" is filled with some data, then sent on
		   the message queue. For now, everything works */

		strncpy(p, answer, LEN);
		p[0] = 'v';

	     /* p = smp1(objs*LEN);            <--- THIS CODE DOESN'T WORK ALSO
		strncpy(p, answer, LEN);
		*(p) = 'v'; */

		printf("Objects (later): %d\n", objs); /* this is OK */
		printf("Entry: \"%s\" (%d; %d)\n", p, strlen(p), LEN); /* this is OK also */
		printf("SHMEM: \"%s\" (%d)\n", smp1, strlen(smp1)); /* HERE IS THE PROBLEM!!! smp1 seems to be *empty* and strlen returns 0 */
	    }
	    else
	    {
		/* do something else */
	    }

	    shmdt(smp1);
	    free(answer);
	    exit(0);
	}
	else /* parent process */
	{
	    int w;
	    w = waitpid(pid, 0, 0|WNOHANG);
	}
}
This is about as I would expect, and smp1 is not empty. You should fix the part of the code that you haven't posted
 
Old 06-28-2005, 06:36 PM   #4
aluser
Member
 
Registered: Mar 2004
Location: Massachusetts
Distribution: Debian
Posts: 557

Rep: Reputation: 43
In particular, is it possible for some other process to set the first byte of smp1 to 0 between the first iteration of the "for (i=0; i<MAX; i++)" loop and the SHMEM printf?

that race will cause your symptom sometimes, but it seems unlikely to happen consistently given the small number of iterations in that loop.

I suppose it's also possible for 'answer' to contain some control characters which erase the 'v' on your terminal. Evidently my malloc() gave me zeroed memory in this case.
 
Old 06-29-2005, 03:34 AM   #5
d1s4st3r
Member
 
Registered: May 2004
Location: Italy
Posts: 70

Original Poster
Rep: Reputation: 16
It's solved!
You're all right, he posted code was right!
After a heavy bug hunting , I found the *REAL* problem:
I got a header file that contains many #defines (where each one defines the lenght of a part of a string).
Well now, there was something like this:
Code:
#define		N		5

#define		A		1
#define		B    		16
#define		C	    	5
#define		D		4
#define 	E    		8
#define 	F		8

#define		MAX_LEN		A+B+C+D+E+F
Ok, I realized only now that the product "N*MAX_LEN" was totally wrong. This because I didn't know the sum "A+B+C+D+E+F" needs to be in round brackets ("(A+B+C+D+E+F)"), otherwise it would be "N*A+B+C+...".
This made a mess with a lot of counters and sizes (but, strangely, everything seemed to work except the shmem stuff).
Now it works fine with my code and shmem behaves it the right way
Many thanks guys!
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
is shared memory expandable in memory size? Thinking Programming 4 08-16-2005 09:57 AM
shared memory/semaphore problem V_Ganesh Programming 1 03-31-2005 10:58 PM
Is Shared Memory bound to a thread in Linux ? colmmagoo Linux - Software 0 09-24-2004 01:13 PM
shared memory socket9001 Programming 4 02-06-2004 02:08 PM
Can LINUX use shared memory? Shirley Linux - General 1 05-24-2002 02:50 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 04:24 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration