Assign array elements to a thread - c

I am a beginner in multithreading and I have an assignment where I need each array element to be represented by a thread and within the thread I have to do some operations with the array element(s). My array represents a "road" where only one passenger can be "in" each array element. I need my passengers to cross the whole road(array) from left to right but asychronously, thats why I need threads. In conclusion I need each passenger/element to "move" one position at the same time (iff there is no another passenger infront of him) until all passengers reach the end of the array/road.
Any way to achieve this?
I have already tried:
void *function(){
for(int i=0;i<array_size;i++){
mutex_lock();
//critical section, manipulating the data
mutex_unlock();
}
void movement(){
while(elements in array){
pthread_t threads[array_size] //i need as much threads as the elements
for(int i=0;i<array_size;i++){
pthread_create(&t[i],NULL,function,NULL);
}
for(int i=0;i<array_size;i++)
pthread_join(t[i],NULL);

Related

Program freezes when setting values in an array using for loops, C Devkitpro 3DS

For a homebrew Minecraft-like clone for the 3DS, I'm attempting to create a data struct called a Chunk that contains a position, and a 3D array of ints, where an int in the array represents a block ID.
It is defined as so:
typedef struct{
Vector3 position; //Vector3 is a struct that simply contains xyz as floats, similar to Unity
int blocks[16][128][16]; //Array of ints, each int represents a block ID
} Chunk;
In order to fill a Chunk, I have a function that takes a pointer to the variable. It is meant to fill the 'blocks' array with the block IDs it should contain.
However, this doesn't happen, and the program hangs on execution.
The function is as so:
void generate_chunk(Chunk *chunk)
{
int newBlocks[16][128][16]; //Create temp 3D array
int x,y,z; //For loop coordinate values
for(x=0; x<16; x++) { //Loop X
for(z=0; z<16; z++) { // Loop Z
for(y=0; y<128; y++) { // Loop Y
//<enum> BLOCK_GOLD_ORE = 6, as a test
newBlocks[x][y][z]=(int)BLOCK_GOLD_ORE; //Set the value in the position xyz of the array to 6
}
}
}
/* The runtime then freezes/crashes whenever the array "newBlocks" is referenced. */
printf("\x1b[14;2Hgenerate_chunk :: %i", newBlocks[0][0][0]); //Debug print //!Crashes
//! vvv Uncomment when I've solved the problem above
//! memcpy(chunk->blocks, newBlocks, sizeof(chunk->blocks)); //Copy the temp array to the struct
}
and is called like:
Chunk newChunk;
generate_chunk(&chunk);
What happens is whenever the array or any of its values are referenced hereafter, the program will hang.
Oddly, if I put the function calling behind an if statement, the program still freezes on the first frame despite it not being called at that moment.
Even more curiously, if I assign the values without for loops like this:
void generate_chunk(Chunk *chunk)
{
int newBlocks[16][128][16]; //Create temp 3D array
newBlocks[0][0][0]=(int)BLOCK_GOLD_ORE; //Set its first value to 6 (enum)
printf("\x1b[14;2Hgenerate_chunk :: %i", newBlocks[0][0][0]); //Debug print, doesnt crash anymore
}
The program no longer hangs. It seems to fail whenever I try to assign values using a for loop. I'm probably missing something obvious, but it's driven me to think that this could even be a problem with the compiler (it probably isnt)
The compiler is GCC under DEVKITPRO.
Thanks!
Okay, it seems that the 3DS does not allow 3D arrays above around [19][19][19], when all sides are equal, though that may be flexible if you make the dimensions unequal.

How to return array with only even/odd numbers and delete the unnecessary cells?

I try to get an array, an number and is_even bool variable from the user and return an only even numbers new array, else return only odd numbers array depending on is_even.
for example: the array {1,2,3,4} and is_even=1 will return {2,4} ,if is_even=0 the returned array will be {1,3}
as I get it I should allocate the array dynamically prior to passing it to a function. what I have done so far is.
I got stuck with the return. I checked whether the content pointed by p is even or odd but how do I erase cells?
#include <stdio.h>
#include <malloc.h>
int *new_array(int *p,int number,int is_even){
int j,i=0;
int counter=0;
if(is_even){
for(j=0;j<number;j++){
if(*(p+j)%2==0){
}
}
return p;
}
}
void main() {
int n,i,is_even;
int *p;
printf("enter number of elements");
scanf("%d",&n); rewind(stdin);
printf("hoose is_even 1 or 0");
scanf("%d",&is_even);rewind(stdin);
p=(int *)malloc(n* sizeof(int));
for(i=0;i<n;i++){
scanf("%d",p+i);
}
p=new_array(p,n,is_even);
for(i=0;i<n;i++){
printf("%4d",*(p+i));
}
}
Part of your problem is that you are not accounting for one of the pieces of information you need to convey to the caller: the effective number of integers in the returned array. Your print loop assumes the same number of elements as were originally read, but by the nature of the function, this will typically be too many.
You ask,
how do I erase cells?
, but "erasure" is not a thing you can do. You can overwrite array elements with different values, but you cannot make an individual array element cease to exist, especially not from the middle of an array. The usual idiom would be to put the elements you want to keep in the initial elements of either the original array or a new one, and return how many elements that is. In the case of a new array, you must also return a pointer to the (dynamically allocated) array. The function signature you present is not adequate, because it provides no good means to return the count of elements.
There is a number of ways to address that. A simple one would be to make number an in/out parameter, by passing a pointer to the number of elements instead of the number of elements value:
int *new_array(int *p, int *number, int is_even) {
// ... 'j' keeps a running count of the number of is_even elements
*number = j; // Write the final number of elements back to the caller
return p; // return the allocated array
}
The details of the implementation would need to change a bit to accommodate the change in type and usage of the number parameter, and also to fix bugs.
You might then call it like so:
p = new_array(p, &n, is_even);
... and afterward continue just as you already were doing.
You could place all of your even/odd numbers at the beginning of the array, realloc() the array for its new size, and send the value of its new length back in your return. but you will need your function to receive (int** Array) in order to change the pointer for the array
so function declaration could be int new_array(int **p ,int number ,int is_even)
The problem is not deleting the cells the problem is that when you delete them your arrays length is not the same anymore..
By the way you can also change the value of length and return the new add for the new array with int* new_array(int *p, int *number, int is_even)

Assigning cards from decks to hands

I have a card game assignment, and I'm confused on how to properly deal the user and the computer 5 cards from the deck using a call by reference. Here is the requirement for the function:this function removes the top card from the deck and returns it to the calling function, while shifting the rest of the deck up one card. Note that the size of the deck must be decremented to reflect the loss of one card (This should be done using Call by Reference).
And here is my current code for the function, but I don't think it's right. Please don't be overly technical, I'm a noob. Thanks.
int popCard(int *size, int deck[])
{
int user[5];
int comp[5];
int i,j;
for(j=0; j<=5; j++)
{
for(i=51; i>=47; i--)
{
user[j]=i;
}
for(i=46; i>=42; i--)
{
comp[j]=i;
}
}
}
A function in C can change the outside world in three ways:
Modify a global variable (yuck. avoid this.)
Return a value (yea! the function accomplished something...here it is)
Modify a value passed as a pointer.
So, let's say you have a "deck" object of some kind, and a "hand" object of some kind, and you want to deal a card. You could write a function that takes a pointer to both a deck and a hand and updates both:
void deal(Deck *deck, Hand *hand);
But probably a better design is one deck function and one hand function (assuming cards are ints, which they ought to be).
int dealfrom(Deck *deck);
void dealTo(Hand *hand, int card);
Then just
dealTo(h, dealFrom(d));
Deck and Hand should be structures that have an array of cards and a current size (and maybe a capacity, and other things as needed).

Implementing arraylist in C

I have created a program to add 2 types of items in to a system. I have created 2 structures for the 2 different items. Currently i have created a method to add items to the system and i store each item in an array.
However i encountered a problem when i was gonna implement the delete feature, the problem is if i have a record at array memory index 2, if i delete it there will be an unused space, between memory index 1 and 3. How can i overcome this ? In java , there is arraylist which dynamically allocates space. In C i know that there is dynamic memory allocation , but how can i implement it work with the delete feature ?
Here is what i have done so far :-
#include <stdio.h>
#include <string.h>
struct routers
{
int Device_No;
char Device_Name[30];
int No_of_items;
int Price;
char Description[30];
};
/**declared an of struct routers to store the structure objects
**/
struct routers routerlist[5];
struct controllers
{
int Device_No;
char Device_Name;
int No_of_items;
int Price;
char Description[30];
};
void AddNewItem();
int main()
{
AddNewItem();
return 0;
}
void AddNewItem(){
int item;
int choice=0;
int arraysize=0;
do{
printf("Press 1 to add a Router \nPress 2 to add a controller \n");
scanf("%d",&item);
printf("%d",item);
if(item==1){
printf("\nEnter Device No:\n");
scanf("%d",&routerlist[arraysize].Device_No);
printf("Enter Device Name\n");
fflush(stdin); //flush the buffer
gets(routerlist[arraysize].Device_Name);
printf("Enter Number of Items\n");
scanf("%d",&routerlist[arraysize].No_of_items);
printf("Enter price\n");
scanf("%d",&routerlist[arraysize].Price);
printf("Enter description\n");
fflush(stdin);
gets(routerlist[arraysize].Description);
}
arraysize++;
printf("Do you want to add another item? \nPress 1 to add \nPress 2 to Cancel\n");
scanf("%d",&choice);
}while(choice==1);
}
Thank you for your time.
Depending on your time complexity requirements, there are basically two approaches:
Use a list. A list is a data structure where every item knows where the next item is stored. This is usually implemented by the data structure holding a pointer to two objects of its own kind (the previous one and the next one). That way, when an item is deleted, the pointers of the next and previous items can be adjusted so that the gap is closed.
This means, deleting an element is very fast, but accessing an element by position requires searching for the element from the beginning, which is very slow.
Use an array. An array is a data structure where items are stored consecutively. When an item is deleted, the gap is filled by shifting the following elements.
This means, accessing an element by position is very fast, because only arithmetic operations are involved, but deleting an element is very slow, because a possibly large number of elments have to be copied.
Deleting a gap means moving what's after it, so if you delete index 2 the item at index 3 is moved to index 2, then item at index 4 is moved to index 3, and so on.
In C you can use the memmove function for this, or write a loop.
To implement the similar behavior like in arrayList you need to dynamically allocate memory each time the array is full. Then copy all the members of the current list to that memory
In case of deletion you will have to move the elements one space to the deleted element location. This is similar to how vector are implemented in c++. Please refer this answer of mine Vector implementation, this implementation is in c++. The concept you have to look into this code is how a memory is allocated dynamically when required.
So your approach should be as follows:
Initially allocate some memory spaces
Use them until you reach the final allocated block
In case more memory is required allocate new space . Please use realloc here you will find the advantage of it
free the previously allocated memory and let the previous pointer point to this new location.
Similarly when deleting the elements just move all the elements one space from end towards that element.

Keeping only a few changes from the data structure

I was not sure, about the title of the question, but here's the problem.
I have an array of structures, now I pass it by reference to a function, where in, I have a priority queue, of the same structures.
Now, I process my array, by making use of the priority queue, and in the end of the process, I will have two of the attributes(say A and B) of my structure, in array changed, while I want only one of the change(A) to be reflected outside the function, and I want the other(B) change to be restored, the way it was before passing the array. I have to do it, because for the second time when I have to process the same array, but with different parameters, I want the changes of A to remain, but B to not.
What I do right now is that, after the process, once I am out of the function, I process the entire array, and where ever I have the value changed for attribute B I revert it back to the initial value. Now this is obviously a O(n2) operation which is no good for me.
Can I do something to make it more efficient.
I am working with C.
If your B is of type bool for example, you can create a bool array in the function. Use the indices of the input array (integers) in the priority queue instead of structures. Use the bool array to access the Bs of the input array:
void func(Type *Input, size_t n)
{
bool B[n];
queue<size_t> pqueue;
for (size_t i = 0; i < n; i++)
B[i] = Input[i].B;
size_t index;
while (index = pqueue.front()) {
// do something with Input[index]
// B[index] = false;
// rest of the function
}
}

Resources