ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
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...
#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
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.
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!
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.