multiple dynamic arrays inside a struct - arrays

i am trying do dynamicly allocate a matrix which is inside a struct, also if anyone can also tell me how to send it to the function so i don't have to declare my struct variable globally i would really apreciate it, cuz i can't seem to figure it out
#include <stdio.h>
#include<stdlib.h>
#include <stdbool.h>
struct matrice_dinamica{
int linii, coloane;
int **matrice;
};
struct matrice_dinamica* v = NULL;
void comanda_L_citire_matrice(int i)
{
scanf("%d %d", &v[i].linii, &v[i].coloane);
int v[i].(*matrice)[v[i].coloane] = malloc (sizeof(int[v[i].linii][v[i].coloane]));
for(int x = 0; x < v[i].linii; x++){
for(int y = 0; y < v[i].coloane; y++){
scanf("%d", &v[i].matrice[x][y]);
}
}
}
int main(int argc, char const *argv[])
{
v = (struct matrice_dinamica*)malloc(sizeof(struct matrice_dinamica));
there are more things in the main function so i only gave what i thought usefull cuz the error i get is in the function
the error i get is error: expected expression before '.' token

To avoid double pointers, int **matrice cannot be used because that is a double pointer. The storage for the matrix can be "flattened" into a single dimension and the positions of the elements for each (row,column) coordinate can calculated arithmetically as row * num_columns + column. For example:
struct matrice_dinamica{
int linii, coloane;
int *matrice; // flattened
};
// Get pointer to start of a row
int *matrice_row(struct matrice_dinamica *m, int x)
{
return m->matrice + x * m->coloane;
}
// Get pointer to an element
int *matrice_elp(struct matrice_dinamica *m, int x, int y)
{
return matrice_row(m, x) + y;
}
// Get value of an element
int matrice_el(struct matrice_dinamica *m, int x, int y)
{
return *matrice_elp(m, x, y);
}
// Store value in an element
void matrice_el_store(struct matrice_dinamica *m, int x, int y, int val)
{
*matrice_elp(m, x, y) = val;
}
void comanda_L_citire_matrice(struct matrice_dinamica *m)
{
int *md;
scanf("%d %d", &m->linii, &m->coloane);
m->matrice = malloc(m->linii * m->coloane * sizeof(int));
md = m->matrice;
for(int x = 0; x < m->linii; x++){
for(int y = 0; y < m->coloane; y++){
scanf("%d", md++);
}
}
}

Related

How to access the attributes of a struct in a 2D array

I have a simple program that makes a 2d array of a struct. I want to know how to manipulate the struct's attributes. This is my attempt; i keep getting Segmentation fault, the problem happens in the fillarr method;
My problem is that i don't quite understand how to manipulate the data once it is in a 2D array. I understand that arrays are pointers, my assumption at first was that i could do something like
arr[h][w]->one = 'b';
Which i now know is obviously wrong because the compiler really doesn't like it.
Now, when i try
arr[h][w].one = 'a'
The compiler doesn't complain about that syntax, but this is where my segmentation fault triggers.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node {
char one;
char two;
};
typedef struct node node;
node** makeArr(int h, int w) {
printf("Making arr\n");
node** output = (node**)malloc(sizeof(node*) * h);
for (int i = 0; i < h; i++) {
output[i] = (node*)malloc(sizeof(node) * w);
}
return output;
}
void killarr(node **arr, int h, int w) {
printf("Killing arr\n");
for (int i = 0; i < h; i++) {
free(arr[i]);
}
free(arr);
}
void fillarr(node **arr, int h, int w) {
printf("Filling arr\n");
char x = 'a';
for (int i = 0 ; i < h; i++) {
for(int m = 0; m < w; m++){
arr[h][w].one = x++; // <- here exactly
arr[h][w].two = x++; // <- here too
}
}
}
int main(int argc, char *argv[]) {
int h = 10;
int w = 10;
node **arr = makeArr(h, w);
fillarr(arr, h, w);
killarr(arr, h, w);
}
Each time through the inner loop you're accessing arr[h][w]. But since h and w are the array bounds, you're accessing out of bounds, leading to undefined behavior.
You likely meant:
arr[i][m].one = x++;
arr[i][m].two = x++;

I am getting Segmentation fault: 11

I am getting error on the line where I put "<<--" (line 9) sign. it didn't had any compiling error , but while giving input it says "Segmentation fault: 11". I don't know what went wrong.
input:
3 3
1 1 1
2 2 2
3 1 5
The code:
#include <stdio.h>
#include <stdlib.h>
int comp (const void * x, const void * y)
{
int *a = *(int **)x;
int *b = *(int **)y;
//getting error here
if (a[0] == b[0]) // <<-- here
{
if (a[2] == b[2])
{
return -(a[1] - b[1]);
}
else
{
return a[2] - b[2];
}
}
else
{
return a[0] - b[0];
}
}
int main()
{
int n;
long long d;
scanf("%d %lld", &n, &d);
int t[n][3];
for (int i = 0; i < n; i++)
{
scanf ("%d %d %d", &t[i][0], &t[i][1], &t[i][2]);
}
printf("%lu\n", sizeof(t[0]));
qsort(t, n, sizeof(t[0]), comp);
for (int i = 0; i < n; ++i)
{
printf("%d-%d-%d\n", t[i][0], t[i][1], t[i][2]);
}
}
Can anyone help me with this?
Your
int t[n][3];
array is actually an 1D array consisting of n 1D arrays of type int [3]. These int [3] objects is what you are trying to sort by your
qsort(t, n, sizeof(t[0]), comp)
call.
So, in order to properly compare these objects you have to interpret the parameters of your comparison callback as pointers to int [3] objects. Meanwhile, your current implementation of comp is written as if the parameters are pointing to int * objects, which is incorrect. int [3] and int * are two very different things.
This is how you can do it
int comp (const void * x, const void * y)
{
int (*a)[3] = x;
int (*b)[3] = y;
// And now compare the arrays by accessing them as `(*a)[1]`,
// `(*b)[2]` and so on
}
Alternatively, you can write the comp prologue code as
int comp (const void * x, const void * y)
{
const int *a = *(int (*)[3]) x;
const int *b = *(int (*)[3]) y;
// And now compare the arrays by accessing them as `a[1]`,
// `b[2]` and so on, i.e. keep the rest of your code unchanged
}
This assumes that the rest of your comparison logic is correct. Note though that comparing int values by subtracting them from each other is risky, since it can overflow.

Getting the address of function return arguement in C

Having read the chapter about sttructures from "The C programming Language book" I tried the following code. The goal is to have an array of pointer initialized with some specific value for all its points.
#include <stdio.h>
#define MAXPOINTS 1000
struct point {
int x;
int y;
};
struct point makepoint(int x, int y);
int main(int argc, const char *argv[])
{
int i;
int number1 = 5, number2 = 10;
struct point *points[1000];
for (i=0; i< MAXPOINTS; i++) {
points[i] = &(makepoint(number1, number2));
}
}
struct point makepoint(int x, int y) {
struct point my_point;
my_point.x = x;
my_point.y = y;
return my_point;
}
The error generated after running the above code is the following:
test_something.c:18:22: error: cannot take the address of an rvalue of type 'struct point'
Why does this happen since the makepoint function does return a valid point object?
Thanks in advance,
You are returning a temporary copy of a point and take his address is not a good idea.
Try this:
struct point* makepoint(int x, int y);
int main(int argc, const char *argv[]) {
int i;
int number1 = 5, number2 = 10;
struct point* points[MAXPOINTS];
for (i=0; i< MAXPOINTS; i++)
points[i] = makepoint(number1, number2);
for (i=0; i< MAXPOINTS; i++)
free(points[i]);
return 0;
}
struct point* makepoint(int x, int y) {
struct point* my_point = malloc(sizeof(struct point));
my_point->x = x;
my_point->y = y;
return my_point;
}
Anyway, in your code:
struct point *points[10];
for (i=0; i< MAXPOINTS; i++) {
points[i] = &(makepoint(number1, number2));
}
...you have an array of 10 pointers and you're trying to assign 1000 pointers (MAXPOINTS).
You cannot take the address of a value, only of a variable. This is because values don't necessarily need to live in (addressable) memory. For example: the return value of a function is (usually) passed via a register, and you cannot take the address of a register(-variable).
You could instead change your makepoint function to take a pointer to a struct point and fill it in:
struct point makepoint(struct point * in, int x, int y){
in->x = x;
in->y = y;
return *in;
}
Note that the return value isn't strictly necessary, but kept for 'backward compatability'.

Why can't I return this array?

Why am I getting the following errors?
randmst.c: In function ‘main’:
randmst.c:41: error: variable-sized object may not be initialized
randmst.c: In function ‘createGraph’:
randmst.c:84: warning: return from incompatible pointer type
randmst.c:84: warning: function returns address of local variable
createGraph() creates an array of pointers (called VertexPointer) to structs. Once it's created, I'm having trouble passing it back to main().
int main(int argc, char **argv){
//command line arguments
int test = atoi(argv[1]);
int numpoints = atoi(argv[2]);
int numtrials = atoi(argv[3]);
int dimension = atoi(argv[4]);
//perform trials, put results in an array
int i;
int trials[dimension];
for(i = 0; i < numtrials; i++){
VertexPointer graph[numpoint= createGraph(numpoints, dimension);
//testing
int y;
int i;
for(y = 0; y < numpoints; y++){
for(i = 0; i < dimension; i++){
printf("%f \n", (*graph[y]).loc[i]);
}
printf("\n");
}
}
}
//an array of pointers holding the vertices of the graph
VertexPointer
createGraph(int numpoints, int dimension){
//seed the psuedo-random number generator
srand(time(NULL));
//declare an array for the vertices
VertexPointer graph[numpoints];
//create the vertices in the array
int x;
int z;
for(x = 0; x < numpoints; x++){
//create the vertex
VertexPointer v;
v = (VertexPointer)malloc(sizeof(Vertex));
(*v).key = 100;
//(*v).prev = 0;
//multiple dimensions
for(z=0; z < dimension; z++){
(*v).loc[z] = rand_float();
}
//put the pointer in the array
graph[x] = v;
}
return graph;
}
C does not allow you to return arrays. Even if it did, your code declares that createGraph returns a VertexPointer, not an array of them. malloc an array of pointers, change your code to return VertexPointer *, and use a pointer instead of an array in main.
VertexPointer *
createGraph(int numpoints, int dimension) {
...
VertexPointer *graph = malloc(numpoints * sizeof(*graph));
...
return graph;
}
int main(int argc, char **argv) {
...
VertexPointer *graph = createGraph(numpoints, dimension);
...
}

C pass pointer to function, how to?

Having the following code, how can I have "get" receive a map, and return the value at the specified position?
I am attempting to write a cellular automaton in C to try to wrap my head around pointers and memory allocation. Everything was fine until I decided to make "get" to obtain data instead of a direct map[x+world.w*y] as I used to.
I require this because in the future, I plan to have two maps of the same size, and use the same function to get data from them (so it'd be "get(&map2, x, y)" instead of "get(&map, x, y)".
I do this because I was advised against using globals, so I will keep the two maps in main and send their addresses to functions to process.
This is C language, so no C++ solutions are valid.
I tried to search for this in google but all documentation is extremely technical and convoluted, and I am not sure of how this procedure is actually named... So, can anyone help me with this? How can I pass a malloc'ed array to a function and retrieve or alter data from it?
typedef struct Map {
int HP;
int type;
unsigned int flags;
} Map;
typedef struct World {
int w;
int h;
} World;
struct World world;
int tile (int x, int y) { return x + world.w * y; }
int get (/*unknown*/map , int x, int y){
int val = x + world.w * y;
return /*unknown ->?*/ type;
}
int main (){
Map* map;
world.w = 8;
world.h = 8;
int tiles = world.w * world.h;
map = (Map*)malloc(sizeof(Map) * tiles);
int i;
for(i = 0; i < tiles; i++){
map[i].type = rand()%2;
}
int x,y;
while(1){
put(0,0);
for(y = 0; y < world.h; y++){
printf("\n");
for(x = 0; x < world.w; x++){
printf("%i ", get(&map, x, y));
}
}
};
printf("\n");
return 0;
}
Instead of:
get(&map, x, y)
in which you pass the address of the address of the map pointer that malloc() returned, just pass the address itself:
get(map, x, y)
AFAICT from your code, malloc( ) returns exactly the thing that get( ) is looking for, i.e., a pointer to someplace in memory that has room for 64 tiles. So get( ) could look something like:
int
get( Map *map, int x, inty ) {
int val = x + map->w * y; // map is a pointer to struct, not the struct itself
return val; // get( ) returns an int, and it's in val
}
That might be closer to what you want.
-- pete
There are a few other errors in your code, too, but this might let the compiler get off the ground.
Your map variable in main() is already a Map * so don't create a double-indirect pointer out of it by appling & to it at the call site.
Also, int get(Map *m, int x, int y) { ... return map[...]; }
Don't cast the return value from malloc(3).
I may be wrong but from reading your question, it doesn't sound like you are really looking for a function pointer, rather a pointer to a Map structure to pass to a function. Perhaps you want to return a pointer to a particular Map element as well. If this is the case it would look something like the following:
typedef struct Map {
int HP;
int type;
unsigned int flags;
} Map;
typedef struct World {
int w;
int h;
} World;
struct World world;
int tile (int x, int y) { return x + world.w * y; }
Map * get (Map *map , int x, int y){
return map[x + world.w * y];
}
int main (){
Map *map;
Map *m;
world.w = 8;
world.h = 8;
int tiles = world.w * world.h;
map = (Map*)malloc(sizeof(Map) * tiles);
int i;
for(i = 0; i < tiles; i++){
map[i].type = rand()%2;
}
int x,y;
while(1){
put(0,0);
for(y = 0; y < world.h; y++){
printf("\n");
for(x = 0; x < world.w; x++){
m = get(map, x, y); // map was already declared as a pointer
printf("%d\n", m->HP);
printf("%d\n", m->type);
printf("%X\n", m->flags);
}
}
};
printf("\n");
return 0;
Passing a pointer to a struct (or union) in C is easy:
typedef struct Foo
{
int a ;
char b[32] ;
} FOO ;
void do_something_with_a_foo( FOO* p )
{
// using the arror operation '->' to deference a structure pointer
int m = p->a ;
char n = p->b[3] ;
// using the * operator to deference a structure pointer
int x = (*p).a ;
char y = (*p).b[3] ;
return ;
}
void pass_a_foo_pointer_to_function()
{
FOO stack_instance = { 3 , "hello, world" , } ;
FOO* heap_instance = malloc( sizeof(FOO) ) ;
heap_instance->a = 12 ;
strcpy( heap_instance->b , "this, that and the other" ) ;
do_something_with_a_foo( &stack_instance ) ;
do_something_with_a_foo( heap_instance ) ;
free( heap_instance) ;
return ;
}
Cheers!

Resources