Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Why don't values in my structs stay when I assign values to them?

Posted on 2003-03-06
10
Medium Priority
?
242 Views
Last Modified: 2010-04-15
if I had the following files with the following code:
#######################################################
A.h
---

#ifndef A_H
#define A_H
#include <semaphore.h>
typedef struct {
  char *name;
  int value;
} structOne;

int funciton_1(structOne *mutex);

int function_2(structOne *mutex);

#endif


########################################################
A.c
---
#include <stdlib.h>
#include <stdio.h>
#include <semaphore.h>

#include "A.h"


int function_1(structOne *mutex)
{
  mutex->value = 1;
  return 0;
}

########################################################
program.c
---------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>

#include "circ_buffer.h"
#include "A.h"

static char *message = "A Message";

static const unsigned int SIZE = 5;
static circ_buffer_t cb;

static void *producer(void *arg);
static void *consumer(void *arg);

structOne mutex;    

int main(void)
{
   int i;
   pthread_t PID, CID;    //define the producer and consumer threads
    void *junk;

   function_1(&mutex);  //SETS 'value' TO 1 within the struct

   circ_buffer_init(&cb, SIZE);  //initialize a circular buffer to SIZE
       
   pthread_create(&PID, NULL, producer, junk);
   pthread_create(&CID, NULL, consumer, junk);
   

  /*****joins threads together*****/
  pthread_join(PID, NULL);
  pthread_join(CID, NULL);

  /****clean up****/
  function_destroy(&mutex); // forgot to include this in the header 'A.h' but it should be there (basically it destorys the semaphore)
  pthread_exit(NULL);

  circ_buffer_destroy(&cb);
  return 0;
}


int function_1(structOne *mutex)
{
  if (mutex->value > 1)  // HERE's THE PROBLEM... I can't do this for some reason, I get the address or some big integer number not the '1' I previously set this value to in my main function.  This is the same for all the other comparisons with 'mutex->value'
    {
      ...    
    }

  if (mutex->value == 1)
    {
      mutex->mutexValue--;
    }
  else if (mutex->mutexValue == 0)
    {
      ...
    }
 
  return 0;
}


So basically what am I doing wrong?  I want the struct to retain the value I assigned it in main so that I can do some comparisons in subsequent functions.
0
Comment
Question by:CBMLude
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 3
  • 2
  • +2
10 Comments
 
LVL 1

Expert Comment

by:helmet275
ID: 8078405
did you initialize mutex?  You might type calling your parameters to your functions something other than the name of your global variable.  
0
 

Expert Comment

by:gotenks
ID: 8078494
is this correct anyway, cos i see two function_1() in your code.

int main() {
   ...
   function_1(&mutex);

   return 0;
}

i see no mistake for this if you use the function_1() declared in A.c
but if you are using the second function_1() {the one below the main() }, then you won't be getting 1 cos you haven't initialize the mutex.value yet.
or have i overlook somewhere?
0
 

Author Comment

by:CBMLude
ID: 8078523
oops... sorry the last function should be
int function_2(structOne *mutex)
{

}
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 

Author Comment

by:CBMLude
ID: 8078592
argh... sorry.. I messed up again... that function
'function_2(structOne *mutex)' should be in file 'A.c'

and in file: program.c, there should be another function called
void *producer(void *arg)
{
   function_2(*arg);
}

Here's the entire thing again so it's doens't look hard to read it:

if I had the following files with the following code:
#######################################################
A.h
---

#ifndef A_H
#define A_H
#include <semaphore.h>
typedef struct {
 char *name;
 int value;
} structOne;

int funciton_1(structOne *mutex);

int function_2(structOne *mutex);

#endif


########################################################
A.c
---
#include <stdlib.h>
#include <stdio.h>
#include <semaphore.h>

#include "A.h"


int function_1(structOne *mutex)
{
 mutex->value = 1;
 return 0;
}

int function_2(structOne *mutex)
{
if (mutex->value > 1)  // HERE's THE PROBLEM... I can't do this for some reason, I get the address or some big integer number not the '1' I previously set this value to in my main function.  This is the same for all the other comparisons with 'mutex->value'
   {
     ...    
   }

 if (mutex->value == 1)
   {
     mutex->mutexValue--;
   }
 else if (mutex->mutexValue == 0)
   {
     ...
   }
 
 return 0;
}

########################################################
program.c
---------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>

#include "circ_buffer.h"
#include "A.h"

static char *message = "A Message";

static const unsigned int SIZE = 5;
static circ_buffer_t cb;

static void *producer(void *arg);

structOne mutex;    

int main(void)
{
  int i;
  pthread_t PID, CID;    //define the producer and consumer threads
   void *junk;

  function_1(&mutex);  //SETS 'value' TO 1 within the struct

  circ_buffer_init(&cb, SIZE);  //initialize a circular buffer to SIZE
     
  pthread_create(&PID, NULL, producer, junk);
  pthread_create(&CID, NULL, consumer, junk);
   

 /*****joins threads together*****/
 pthread_join(PID, NULL);
 pthread_join(CID, NULL);

 /****clean up****/
 function_destroy(&mutex); // forgot to include this in the header 'A.h' but it should be there (basically it destorys the semaphore)
 pthread_exit(NULL);

 circ_buffer_destroy(&cb);
 return 0;
}


void *producer(void *arg)
{
   function_2(&mutex);
}


So basically what am I doing wrong?  I want the struct to retain the value I assigned it in main so that I can do some comparisons in subsequent functions.
0
 
LVL 5

Expert Comment

by:Kocil
ID: 8084468
Don't use the junk, use this instead.

pthread_create(&PID, NULL, producer, &mutex);
pthread_create(&CID, NULL, consumer, &mutex);
0
 
LVL 1

Expert Comment

by:jcaldwel
ID: 8084809
Why are you reinventing mutex? What functionality do you need that POSTIX Thread Mutexes don't provide?

0
 

Expert Comment

by:gotenks
ID: 8085017
hmm, still could not see any mistake though.
maybe you should try to do what Kocil suggested and rewrite your producer function to this :

void * producer (void * arg) {
   function_2((structOne *)arg);
   ...
}

int main() {
   ...
   pthread_create(&PID, NULL, producer, &mutex);
   ...
}

hope this will help?
0
 
LVL 5

Expert Comment

by:Kocil
ID: 8085995
The reason why don't use junk is because junk is allocated in the stack, while mutex is in data segment.

This is the more elegant solution

StructOne mutex;

main()
{
 ...
 pthread_create(&PID, NULL, consumer, (void*) &mutex);
 ...
}

void consumer(void *arg)
{
  StructOne *mutex = (StructOne*) arg;

  /* you may use the local mutex pointer */
  ...

}
0
 

Author Comment

by:CBMLude
ID: 8086415
Kocil:
actually that wasn't the problem, for some reason if I changed the arguement for the prototypes in file 'A.c' to int function_1(structOne *m) and int function_2(structOne *m) it worked.

BUT..... after I assign the value: 'm->value = 1' (in function_1) and in function_2 try to access m->value I get '1' when the first thread tries to access that value.  When a 2nd thread gets into function_2, m->value is no longer 0 or 1 (depending if I did anything to it when the first thread got there first), it's a LARGE integer again, and I don't know what that is (probably the address I'm assumming).  Why is that?


jcaldwel:
I don't fully understand the usage of semaphores, and I've looked around online and found many places with sample code on how to rewrite semaphores with pthreads, I assume you can do it the other way around.  Besides playing around with this stuff is the best way to learn it.
0
 
LVL 5

Accepted Solution

by:
Kocil earned 75 total points
ID: 8089271
Yea you right, it is better
void consumer(StructOne *mutex)
{
 /* you may use the local mutex pointer */
 ...
}

LARGE because it haven't initialized. It can be anything.
So I think you have to make sure that thread producer gets to the mutex first, maybe the main() can sleep for a while after creating the producer.
Another options is to initialize the mutex on main() before creating the threads.

Cheers

0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Summary: This tutorial covers some basics of pointer, pointer arithmetic and function pointer. What is a pointer: A pointer is a variable which holds an address. This address might be address of another variable/address of devices/address of fu…
Examines three attack vectors, specifically, the different types of malware used in malicious attacks, web application attacks, and finally, network based attacks.  Concludes by examining the means of securing and protecting critical systems and inf…
The goal of this video is to provide viewers with basic examples to understand opening and writing to files in the C programming language.
The goal of this video is to provide viewers with basic examples to understand how to create, access, and change arrays in the C programming language.

722 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question