2D array as pthread function argument - c

I am trying to pass a 2d array into a pthread function, but I can not find a way to get access to the array content during pthread process, how can I do it?
I tried
int ** array = (int **)arg;
but it caused segfault after I tried to change the stored value;
Here is part of my code:
int message1[2][64];
int i = 0;
for (; i < 2; i++)
{
int j = 0;
for (; j < 64; j++)
{
message[i][j] = 1;
}
}
pthread_t tid[1];
pthread_create(&tid[0], NULL, xD, message);
the function:
void * xD(void * arg)
{
int ** array = (int **)arg;
array[0][0] = 2;
}

Couldn't find a proper duplicate for this. int ** is not a 2D array but a pointer to a pointer to an int.
What you want to pass in is a pointer to an array[64] of int, i.e. int (*array)[64].
Try
int (*array)[64] = arg;

Related

inicializing a structure with arrays of arrays [duplicate]

I'm trying to create a function that creates a variable sized 2D funct array. I'm using the following code, which seems to work just fine on its own:
typedef struct
{
//Starter Properties
int TypeB;
int TypeF;
int TypeW;
//Randomized Properties
int RandB;
int RandF;
int RandW;
//Derived Properties
int Speed;
} MapTileData;
MapTileData **Map;
int i, x=5, y=5;
//Allocate Initial Space
Map = (MapTileData**)calloc(x, sizeof(MapTileData));
for(i = 0; i < x; i++)
{
Map[i] = (MapTileData*)calloc(y, sizeof(MapTileData));
}
So the above code creates a 2D struct array. My attempts to move the code to a function have been less successful, giving segmentation faults when trying to print the array:
void CreateMap(MapTileData **Map, int xSize, int ySize)
{
//Variables
int i;
//Allocate Initial Space
Map = (MapTileData**)calloc(xSize, sizeof(MapTileData));
for(i = 0; i < xSize; i++)
{
Map[i] = (MapTileData*)calloc(ySize, sizeof(MapTileData));
}
}
Used in the code:
MapTileData **MapTile;
CreateMap(MapTile,5,5);
Any and all help is greatly appreciated!
Function arguments are passed by value in C and modifying arguments in callee won't affect caller's local variables.
Use pointers to modify caller's local variables.
void CreateMap(MapTileData ***Map, int xSize, int ySize)
{
//Variables
int i;
//Allocate Initial Space
*Map = calloc(xSize, sizeof(MapTileData));
for(i = 0; i < xSize; i++)
{
(*Map)[i] = calloc(ySize, sizeof(MapTileData));
}
}
Usage in the code:
MapTileData **MapTile;
CreateMap(&MapTile,5,5);
Alternate way: Pass the allocated array via the return value.
MapTileData **CreateMap(int xSize, int ySize)
{
//Variables
MapTileData **Map;
int i;
//Allocate Initial Space
Map = calloc(xSize, sizeof(MapTileData));
for(i = 0; i < xSize; i++)
{
Map[i] = calloc(ySize, sizeof(MapTileData));
}
//Return the value
return Map;
}
Usage in the code:
MapTileData **MapTile;
Maptile = CreateMap(5,5);
Also note that they say you shouldn't cast the result of malloc() and its family in C.

parse 2d dynamic int array to Shared Memory

Im trying to build a program that parsing a 2d dynamic array to other program by using shared memory.I search a lot but im a bit confused because im not familiar at this one.
My code so far:
int main (int argc, char* argv []){
int rows,columns;
if( argc < 3 ){
printf("Need The size of the 2d array\n");
return 0;
}
rows = atoi(argv[1]);
columns = atoi(argv[2]);
time_t t;
srand((unsigned) time(&t));
key_t key = ftok(".",'a');
size_t size = sizeof(key_t) + (rows * columns + 2 + rows) * sizeof(int);
int shmid = shmget(key,size,IPC_CREAT|IPC_EXCL|S_IRWXU);
int *memory = shmat(shmid, NULL, 0);
printf("Shared Memory Key: %d\n", key);
int *argsflag = memory;
int *resflag= memory + 1;
int *res = memory + 2;
int **array = (int **) memory + (rows*columns);
for(int i = 0; i < rows ; i++) {
for(int j = 0; j < columns; j++) {
array[i][j] = rand() % 100;
}
}
for(int i = 0; i < rows ; i++) {
for(int j = 0; j < columns; j++) {
printf("%d ",array[i][j]);
}
printf("\n");
}
shmctl(shmid,IPC_RMID,NULL);
shmdt(memory);
return(0);
}
Im getting a Segmentation fault (core dumped) and i dont know why.Also by searching i find a solution with struct but i dint get how i can build that.
You cannot have a int** point at a 2D array. It can only point to the first element in a 1D array of int*.
Furthermore, what's the logic of memory + (rows*columns)? You end up setting the pointer to the last item of the array, rather than the first.
Try this instead:
void* memory = shmat( ...
...
int (*array)[columns] = memory;
...
array[i][j] = ... ;
Where int (*array)[columns] is an array pointer, which ends up point at the first array in the 2D array.
For details, see Correctly allocating multi-dimensional arrays.

Function to initialize two dimensional array

I have a c program in which I want to initialize a 2 dimensional array.
So I made this function :
void initLayer(int **layer, int *dimensions) {
printf("initLayer\n");
layer = malloc(sizeof(int*) * dimensions[0]);
for (int i = 0; i < dimensions[0]; i++) {
layer[i] = malloc(sizeof(int) * dimensions[1]);
}
}
When I use this function there is no problem, but when I try to read the 2D array later I always get a segmentation fault.
I think it may be because the initialization made in the function are not saved when its finished.
Do you know how I could correct my function ? Thank you in advance.
To passing pointer to function you need one more pointer.
int **matrix; is an array of arrays, so to fill it you need to pass it as a pointer, which is int ***layer. but it is weird.
also for changing data by pointer you need to add a star * before it. *layer = ...
#include <stdlib.h>
void initLayer(int ***layer, int *dimensions)
{
*layer = malloc(sizeof(int *) * dimensions[0]);
for (int i = 0; i < dimensions[0]; i++)
{
*(*layer + i) = malloc(sizeof(int) * dimensions[1]);
}
}
int main()
{
int **matrix;
int dimensions[2] = { 4, 6 };
initLayer(&matrix, dimensions);
// then do whatever you want
for (int i = 0; i < dimensions[0]; i++)
{
for (int j = 0; j < dimensions[1]; j++)
{
matrix[i][j] = i * j;
}
}
}
as for me, better to use typedef to make code more readable:
#include <stdlib.h>
typedef int * Array;
typedef int ** Matrix;
void initLayer(Matrix *layer, Array dimensions)
{
*layer = malloc(sizeof(Array) * dimensions[0]);
for (int i = 0; i < dimensions[0]; i++)
{
(*layer)[i] = malloc(sizeof(int) * dimensions[1]);
}
}
int main()
{
Matrix matrix;
int dimensions[2] = { 4, 6 };
initLayer(&matrix, dimensions);
// then do whatever you want
for (int i = 0; i < dimensions[0]; i++)
{
for (int j = 0; j < dimensions[1]; j++)
{
matrix[i][j] = i * j;
}
}
}
When you call the function, the int **layer pointer is copied. So, when you do layer = malloc(...) what actually happens is the function sets its local copy to the malloc result. What you want is to mutate the variable which you called the function with. You can do this by taking a int ***layer and passing in &layer when calling initLayer. Note that you must then use *layer instead of layer in your code.
You have two approaches here:
to pass a reference to the double pointer (***int in this case)
or to return the allocated pointer as the result of your function:
in the first case:
void initLayer(int ***layer, int *dimensions) {
printf("initLayer\n");
*layer = malloc(sizeof(int*) * dimensions[0]);
for (int i = 0; i < dimensions[0]; i++) {
layer[i] = malloc(sizeof(int) * dimensions[1]);
}
}
you pass a reference to a pointer, instead of passing the (uninitialized) pointer. Remember, in C, all parameters are passed by value. In this case, you can call your function as:
...
int**vector;
...
initLayer(&vector, dims); /* you pass the address of your double pointer */
In the second case:
int** initLayer(int *dimensions) {
printf("initLayer\n");
int **layer = malloc(sizeof(int*) * dimensions[0]);
for (int i = 0; i < dimensions[0]; i++) {
layer[i] = malloc(sizeof(int) * dimensions[1]);
}
return layer;
}
in this case, you call it as:
...
int**vector;
...
vector = initLayer(dims); /* you receive your double pointer as a return value */

How to allocate a 2D array of pointers to a struct [duplicate]

This question already has answers here:
How do I correctly set up, access, and free a multidimensional array in C?
(5 answers)
Closed 6 years ago.
This is were I got so far,but I don't know if it's right.
This function receives the dimensions of the 2D array (nxn),and allocates it.
flightInfo is the name of the struct.
Will this work?
thanks in advanced
after allocating the array(ignore the method ,since we are not allowed to use the method you proposed) I would like to initialize the struct (I built a function to do it but it didn't work),I tried to do it right after the allocation and kept getting the" Unhandled exception" warning, does it has to do
with the syntax, am I forgetting a '*'?
void flightMatrix()
{
FILE * fpf;
int checkScan,Origin,Dest;
float time,cost;
char flightName[3];
flightInfo *** matrix;
if(!(fpf=fopen("flights.txt","r")))exit(1);
while((checkScan=fscanf(fpf,"%*10c%3d%3d%3c%5f%7f%*",&Origin,&Dest,flightName,&time,&cost))!=EOF)
{
matrix=allocateMatrix(Dest);
matrix[Origin-1][Dest-1]->o=Origin;
}
}
flightInfo*** allocateMatrix(int n)
{ int i,j;
flightInfo*** matrix;
matrix=(flightInfo***)malloc(sizeof(flightInfo **)*n);
for(i=0;i<n;i++)
matrix[i]=(flightInfo **)malloc(sizeof(flightInfo*)*n);
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < n; ++j)
matrix[i][j] = NULL;
}
return matrix;
}
[http://i.stack.imgur.com/MFC7V.png]
this is what happens when I try to initialize
Technically speaking, this won't create 2D array. The result will be array of pointers, where each one points to different array of pointers to a struct.
The difference is that, memory will be fragmented, so every element will point to some memory location, instead of single continuous memory block.
The common approach for this is to create flatten 2D array:
flightInfo** allocateMatrix(int n)
{
flightInfo** matrix = malloc(n*n * sizeof(*matrix));
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
matrix[i*n + j] = NULL;
return matrix;
}
If you are forced to use two indices, then you could place matrix as function argument:
void allocateMatrix(int n, flightInfo* (**matrix)[n])
{
*matrix = malloc(n * sizeof(**matrix));
for (int i = 0; i < n; ++i)
for (int j = 0; j < n; ++j)
(*matrix)[i][j] = NULL;
}
The second asterisk is required, because pointers are passed by value, otherwise you would end up with modified local copy of the pointer, that does nothing to matrix from main function.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct flightInfo {
char airport[30];
int altitude;
} flightInfo;
void allocateMatrix(int n, flightInfo* (**matrix)[n])
{
*matrix = malloc(n * sizeof(**matrix));
for (int i = 0; i < n; ++i)
for (int j = 0; j < n; ++j)
(*matrix)[i][j] = NULL;
}
int main()
{
int n = 10;
flightInfo* (*matrix)[n];
allocateMatrix(n, &matrix);
matrix[0][0] = malloc(sizeof(flightInfo));
strcpy(matrix[0][0]->airport, "Heathrow");
matrix[0][0]->altitude = 10000;
printf("%s, %d\n", matrix[0][0]->airport, matrix[0][0]->altitude);
}
The another way would be to encapsulate the array within a struct.

Declaring global variable (array) inside a function in C

I need to declare a global two-dimensional array in C.
The size of the array is determined by the width and height of a given picture.
So I first have to load the picture, and only then create the array. But if I want a variable (in this case, my array) to be global, I have to declare it at the top of the file and not inside a function.
So how can I declare a array as global when I only know its size after the execution of the main() function?
EDIT:
(I've also tried the other solutions so this comments refers to all of them)#Mimisbrunnr
First, thanks for the quick response!
I've tried but I can't see to make it work. I'm probably missing something stupid, but how does "array" becomes global? It says on test() that 'array' is undeclared
int *buffer;
int main() {
int i;
int x_size=100;
int y_size=100;
int * buffer = malloc(sizeof(int)*x_size*y_size);
int ** array = malloc(sizeof(int*)*y_size);
for(i = 0; i<y_size; i++) {
array[i]=&buffer[i*x_size];
}
array[0][1] = 5;
test();
return 0;
}
void test(){
printf("%d",array[0][1]);
}
create a global pointer and then malloc the space into it.
char * buffer;
int main(void) {
buffer = malloc( /* Width * Height */ );
}
I didn't actual execute this code, but this should get you started.
int x_size = 100;
int y_size = 100;
int ** array;
array = malloc(sizeof(int *)*y_size);
for(int i = 0; i<y_size; i++)
array[i] = malloc(sizeof(int)*x_size);
larsmans made a good point.
what about this?
int x_size = 100;
int y_size = 100;
int * buffer = malloc(sizeof(int)*x_size*y_size);
int ** array = malloc(sizeof(int *)*y_size);
for(int i = 0; i<y_size; i++)
array[i] = &buffer[i*x_size];
It looks like you might need some basic C tutorial.
int *buffer;
int **array;
int main()
{
int x_size=100;
int y_size=100;
int i;
/*int * */ buffer = malloc(sizeof(int)*x_size*y_size);
/*int ** */ array = malloc(sizeof(int*)*y_size);
for(i = 0; i<y_size; i++)
array[i]=&buffer[i*x_size];
array[0][1] = 5;
test();
return 0;
}
void test()
{
printf("%d",array[0][1]);
}
use a static variable (pointer) and allocate the array dynamically using malloc.

Resources