Struct of Matrices C - c

I have this struct:
typedef struct {
int n;
bool **a;
bool **b;
bool **c;
} matrices_struct;
Then I want to assign a matrix a for a given struct:
void multiplyMatrix(int n, int numOfThreads, bool a[n][n], bool b[n][n], bool c[n][n]){
...
matrices_struct *ms = malloc(sizeof(*ms));
ms->a = a; //doesn't work
...
}
Is it possible to achieve this?

Ok, so I have managed to solve this problem like this:
struct:
typedef struct {
int n;
bool *a;
bool *b;
bool *c;
} matrices_struct;
function:
void multiplyMatrix(int n, int numOfThreads, bool *a, bool *b, bool *c){
...
for(int i = 0; i < numOfThreads; i++){
matrices_struct *ms = malloc(sizeof(*ms));
ms->n = n;
ms->a = a;
ms->b = b;
ms->c = c;
...
}
}
}
function call:
...
bool a[size][size];
bool b[size][size];
bool c[size][size];
fillMatrix(size, a);
fillMatrix(size, b);
multiplyMatrix(size, numOfThreads, *a, *b, *c);
...

Related

How to refactor a function with different struct pointers as parameters?

Suppose I have this piece of code, with 2 structs and a big function that receives this 2 structs as parameters:
typedef struct
{
int field_A;
int field2_A;
} A;
typedef struct
{
int field_B;
int field2_B;
} B;
void function_need_refactor(A *a, B *b)
{
for(i = 0; i < SIZE; i++)
{
do_something(a->field_A);
}
for(i = 0; i < SIZE; i++)
{
do_something(b->field2_B);
}
}
How can I replace the both for loops to a single function? I thought about using void pointer and an identifier for each struct, but couldn't come up with an answer. Is there a clean way to refactor this or is it impossible?
void refactored_function(void* my_struct, char type_identifier)
{
//code to identify the type
for(i=0; i < SIZE; i++)
{
do_something((cast)my_struct->????);
}
}
There are two modifications that come to mind here. First of all, both loops rely on the same counter and the counter is independent of the items in the loop body... Thus, logically, you should at least be able to do this:
typedef struct
{
int field_A;
int field2_A;
} A;
typedef struct
{
int field_B;
int field2_B;
} B;
void function_need_refactor(A *a, B *b)
{
for(i = 0; i < SIZE; i++)
{
do_something(a->field_A);
do_something(b->field2_B);
}
}
But you may also be able to refactor do_something() to operate on both:
typedef struct
{
int field_A;
int field2_A;
} A;
typedef struct
{
int field_B;
int field2_B;
} B;
void function_need_refactor(A *a, B *b)
{
for(i = 0; i < SIZE; i++)
{
do_something(a->field_A, b->field2_B);
}
}
That way, you're only using one loop total, and the function is handling both fields on each loop iteration.

Unexpected error in testing and learning about graphs in C

I have recently started to study this particular book for algorithms and data structure SkienaTheAlgorithmDesignManual.pdf, from which I've heard a lot of praise not only on the Internet,but from my Algorithms Design teacher as well at college,and I ended up having some errors with some code used from the book on page 153(on the book itself) or 165(pdf format).
Here's the code:
#include<stdio.h>
#include<stdbool.h>
#include<stdlib.h>
#define MAXV 1000
typedef struct {
int y;
int weight;
struct edgenode *next;
}edgenode;
typedef struct {
edgenode *edges[MAXV + 1];
int degree[MAXV + 1];
int nvertices;
int nedges;
bool directed;
}graph;
void initialize_graph(graph *g, bool directed);
void read_graph(graph *g, bool directed);
void insert_edge(graph *g, int x, int y, bool directed);
void print_graph(graph *g);
void initialize_graph(graph *g, bool directed) {
int i;
g->nvertices = 0;
g->nedges = 0;
g->directed = directed;
for (i = 1; i <= MAXV; i++) {
g->degree[i] = 0;
g->edges[i] = NULL;
}
}
void read_graph(graph *g, bool directed) {
int i;
int m;
int x, y;
initialize_graph(g, directed);
scanf("%d %d", &(g->nvertices), &m);
for (i = 1; i <= m; i++) {
scanf("%d %d", &x, &y);
insert_edge(g, x, y, directed);
}
}
void insert_edge(graph *g, int x, int y, bool directed) {
edgenode *p;
p = malloc(sizeof(edgenode));
p->weight = NULL;
p->y = y;
p->next = g->edges[x];
g->edges[x] = p;
g->degree[x]++;
if (directed == false)
insert_edge(g, y, x, true);
else
g->nedges++;
}
void print_graph(graph *g) {
int i;
edgenode *p;
for (i = 1; i <= g->nvertices; i++) {
printf("%d ", i);
p = g->edges[i];
while (p != NULL) {
printf(" %d", p->y);
p = p->next;
}
printf("\n");
}
}
main() {
bool directed = true;
graph *g;
read_graph(g, directed);
print_graph(g);
system("pause");
}
Here are the errors:
1>c:\users\dragos\source\repos\learninggraph\learninggraph\main.c(47): warning C4047: '=': 'int' differs in levels of indirection from 'void *'
1>c:\users\dragos\source\repos\learninggraph\learninggraph\main.c(49): warning C4133: '=': incompatible types - from 'edgenode *' to 'edgenode *'
1>c:\users\dragos\source\repos\learninggraph\learninggraph\main.c(65): warning C4133: '=': incompatible types - from 'edgenode *' to 'edgenode *'
1>c:\users\dragos\source\repos\learninggraph\learninggraph\main.c(73): error C4700: uninitialized local variable 'g' used
1>Done building project "LearningGraph.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
I think that the main problem is the "incompatible types",but I may be as very well be wrong.
In insert_edge
p->weight = NULL;
is invalid because weight is an int but NULL a pointer (typically (void*)0)
In insert_edge
p->next = g->edges[x];
is invalid because next is the undefined type struct edgenode * but edges[x] is edgenode *. To solve that you have to replace
typedef struct {
int y;
int weight;
struct edgenode *next;
}edgenode;
by
typedef struct edgenode {
int y;
int weight;
struct edgenode *next;
}edgenode;
The reason is the same in print_graph line
p = p->next;
Explicitly set the return type of main as int
In main you call read_graph with g never set/initialized so when it is dereferenced in read_graph the behavior is undefined, and this is also the case in print_graph. Just replace
graph *g;
read_graph(g, directed);
print_graph(g);
by
graph g;
read_graph(&g, directed);
print_graph(&g);
Full modified version :
#include <stdlib.h>
#include<stdio.h>
#include<stdbool.h>
#define MAXV 1000
typedef struct edgenode {
int y;
int weight;
struct edgenode *next;
}edgenode;
typedef struct {
edgenode *edges[MAXV + 1];
int degree[MAXV + 1];
int nvertices;
int nedges;
bool directed;
}graph;
void initialize_graph(graph *g, bool directed);
void read_graph(graph *g, bool directed);
void insert_edge(graph *g, int x, int y, bool directed);
void print_graph(graph *g);
void initialize_graph(graph *g, bool directed) {
int i;
g->nvertices = 0;
g->nedges = 0;
g->directed = directed;
for (i = 1; i <= MAXV; i++) {
g->degree[i] = 0;
g->edges[i] = NULL;
}
}
void read_graph(graph *g, bool directed) {
int i;
int m;
int x, y;
initialize_graph(g, directed);
scanf("%d %d", &(g->nvertices), &m);
for (i = 1; i <= m; i++) {
scanf("%d %d", &x, &y);
insert_edge(g, x, y, directed);
}
}
void insert_edge(graph *g, int x, int y, bool directed) {
edgenode *p;
p = malloc(sizeof(edgenode));
p->weight = 0;
p->y = y;
p->next = g->edges[x];
g->edges[x] = p;
g->degree[x]++;
if (directed == false)
insert_edge(g, y, x, true);
else
g->nedges++;
}
void print_graph(graph *g) {
int i;
edgenode *p;
for (i = 1; i <= g->nvertices; i++) {
printf("%d ", i);
p = g->edges[i];
while (p != NULL) {
printf(" %d", p->y);
p = p->next;
}
printf("\n");
}
}
int main() {
bool directed = true;
graph g;
read_graph(&g, directed);
print_graph(&g);
system("pause");
}
Compilation :
pi#raspberrypi:/tmp $ gcc -pedantic -Wall -Wextra g.c
pi#raspberrypi:/tmp $
You never allocated any memory for graph *g.
There's no need for this to be a pointer, make it a normal variable and pass its address to the functions.
int main() {
bool directed = true;
graph g;
read_graph(&g, directed);
print_graph(&g);
system("pause");
}

Function to slice an array or struct in c

I have written a function to slice an array in c but it returns addresses I think. I did work correctly once but I screwed up somewhere, any help would be appreciated.
#include <stdio.h>
#include <stdlib.h>
int slice_array(int *input_array, int *sliced_array, int n){
int i;
for(i=0; i < n; i++) {
sliced_array[i] = input_array[i];
return 0;
}
};
struct nbrs_ind {
float value;
int index;
};
//I also want to write a function which can slice the members of struct nbrs_ind (i.e. just slice first n indices nbrs_ind)
int main () {
int k=4;
int i;
int a[7] = {1,2,3,4,6,5,7};
int *ptr_a = a;
int b[k];
int *ptr_b = b;
slice_array(a,b,k);
for(i=0;i<k;i++) {
printf("%d\t",b[i]);
}
printf("\n");
}
~
Update, slicing the array works fine but I want to so the same with struct so far I have written the following code. I get he following error:
assignment from incompatible pointer type [enabled by default]
ptr_A = &A;
#include <stdio.h>
#include <stdlib.h>
//This function works fine in drivers program
void slice_array(int *input_array, int *sliced_array, int n){
int i;
for(i=0; i < n; i++) {
sliced_array[i] = input_array[i];
}
};
struct nbrs_ind {
float value;
int index;
};
//Need to make the slice of nbrs_ind struct using following function.
void slice_struct(struct nbrs_ind *input_struct, struct nbrs_ind *sliced_struct, int n){
int i;
for(i=0; i < n; i++) {
sliced_struct[i].index = input_struct[i].index;
sliced_struct[i].value = input_struct[i].value;
}
};
int main () {
int k=3;
int i;
int a[7] = {1,2,3,4,6,5,7};
float c[7] = {2.3,10,3,5,6.4,7.3,1};
int *ptr_a = a;
int b[k];
int *ptr_b = b;
struct nbrs_ind A[7]; // Declare 7 struct of nbrs_ind
//Initilize the delare structs
for (i=0;i<7;i++){
A[i].index = i;
A[i].value = c[i];
}
//How do I make a pointer to the struct so I can pass it to slice_struct function
// I need to be able to do something like slice_struct(A,B,n);
struct nbrs_ind *ptr_A ;
ptr_A = &A;
slice_array(a,b,k);
for(i=0;i<k;i++) {
printf("%d\t",b[i]);
}
printf("\n");
}
~
~
~
#include <stdio.h>
#include <stdlib.h>
int slice_array(int *input_array, int *sliced_array, int n){
int i;
for(i=0; i < n; i++) {
sliced_array[i] = input_array[i];
}
return 0;
};
struct nbrs_ind {
float value;
int index;
};
//I also want to write a function which can slice the members of struct nbrs_ind (i.e. just slice first n indices nbrs_ind)
int main () {
int k=4;
int i;
int a[7] = {1,2,3,4,6,5,7};
int *ptr_a = a;
int b[k];
int *ptr_b = b;
slice_array(a,b,k);
for(i=0;i<k;i++) {
printf("%d\t",b[i]);
}
printf("\n");
}

[C Programming]Vectors & Pointers

I don't have idea where is the problem but the latest pointer(vector) have some troubles.
First value it's ok (V[0]+T[0]) , S[1] it's always 0 and third value it's random.
#include <stdio.h>
#include <stdlib.h>
int citire_vector(int n, int *V);
void afisare_vector(int n, int *V);
int produs_scalar(int n, int *V, int *T);
int suma_vectori(int n, int *V, int *T);
int main(void)
{
int n, *X, *Y, ps, *S;
printf("n = ");
scanf("%d",&n);
X = (int*) malloc(n*sizeof(int));
Y = (int*) malloc(n*sizeof(int));
citire_vector(n,X);
citire_vector(n,Y);
afisare_vector(n,X);
afisare_vector(n,Y);
ps = produs_scalar(n,X,Y);
printf("Produsul scalar = %d\n",ps);
S = (int*) malloc(n*sizeof(int));
*S= suma_vectori(n,X,Y);
afisare_vector(n,S);
}
int citire_vector(int n, int *V)
{
int i;
for(i=0;i<n;i++)
scanf("%d",V+i);
return *V;
}
void afisare_vector(int n, int *V)
{
int i;
printf("Valorile vectorului sunt:\n");
for(i=0;i<n;i++)
printf("%d ",*(V+i));
printf("\n");
}
int produs_scalar(int n, int *V, int *T)
{
int i, ps = 0;
for(i = 0;i<n;i++)
ps += (*(V+i))*(*(T+i));
return ps;
}
int suma_vectori(int n, int *V, int *T)
{
int i, *U;
for(i=0;i<n;i++)
{
*(U+i )= *(V+i);
}
return *U;
}
Your suma_vectori and its usage are incorrect.
Pointer U inside suma_vectori is uninitialized, causing undefined behavior on assignment
Assignment *S= suma_vectori(n,X,Y) has no effect beyond the initial element of S
To fix this problem, change suma_vectori to return int*, move malloc of the result inside the function, remove malloc for S, and assign S the result of the suma_vectori call:
int *suma_vectori(int n, int *V, int *T); // forward declaration
int *suma_vectori(int n, int *V, int *T) { // Implementation
int *U = malloc(n*sizeof(int)); // do not cast malloc
for(int i=0;i<n;i++) {
U[i] = V[i] + T[i];
}
return U;
}
// call
S= suma_vectori(n,X,Y);
// Don't forget to free malloc-ed memory
free(X);
free(Y);
free(S);
You have to allocate memory to U in suma_vectori function
as it is picking garbage value

function within function by reference in c

i want to pass a function within function by reference in c.They both use the same parameters.This is the code
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
void AtoB(int *A, int *B, int *C, int n,int *h1,int *h2,int *h3 );
void AtoC(int *A, int *B, int *C, int n,int *h1,int *h2,int *h3 );
void BtoC(int *A, int *B, int *C, int n,int *h1,int *h2,int *h3 );
void function2(int *A, int *B, int *C, int n);
int main(){
int n;
int e;
int h3=1;
int h2=1;
int h1=0;
int min;
int *A;
int *B;
int *C;
printf("Give me the number of disks:");
scanf("%d",&n);
A = (int *) calloc(n,sizeof(int));
B = (int *) calloc(n,sizeof(int));
C = (int *) calloc(n,sizeof(int));
min=pow(2,n)-1;
for (e=0;e<n;e++){
A[e]=e+1;
}
if (n%2==0){
for (e=0;e<min/3;e++){
AtoB(A,B,C,n,&h1,&h2,&h3);
}
}
free(A);free(B);free(C);
return 0;
}
int function1(int Z[],int n){
int j,i,k,a;
for (i=0;i<n;i++){
k=n-Z[i];
for (j=0;j<n;j++){
if(k==j){
for(a=0;a<2*Z[i]-1;a++){
printf("%d",Z[i]);
}
}
else if((j==n-1)&&(Z[i]==0)){
printf("|");
}
else{
printf(" ");
}
}
printf("\n");
}for(i=0;i<2*n-1;i++){
printf("-");
}
printf("\n\n");
return 0;
}
void function2(int A[],int B[],int C[],int n){
printf("A\n");
function1(A,n);
printf("B\n");
function1(B,n);
printf("C\n");
function1(C,n);
}
void AtoB(int A[],int B[],int C[],int n,int *h1,int *h2,int *h3){
if (B[n-1]==0){
printf("A->B\n");
B[n-1]=A[*h1];
A[*h1]=0;
*h1=*h1+1;
function2(A,B,C,n);}
else if (A[n-1]==0){
printf("A->B\n");
A[0]=B[n-*h2];
B[n-*h2]=0;
*h2=*h2-1;
function2(A,B,C,n);
}
AtoC(A,B,C,n,&h1,&h2,&h3);
}
void AtoC(int A[], int B[], int C[], int n,int *h1,int *h2,int *h3 ){
}
The program must solve hanoi tower while showing the tower structure.
I am getting error: passing argument 5 of 'AtoC' from incompatible pointer type.Thanks in advance.
You can't do like that, In AtoB function you have declared h1 as a pointer and in AtoC function you are passing address of that pointer. Both functions should have same declaration like that *h1,*h2,*h3.

Resources