convert information of struct of an pointer to array - c

I have a problem with a for loop, which should put information of struct of a pointer to an array. This struct is for complex numbers. The problem is the numbers m[n].re/.im -they are not korrekt.
typedef struct
{
float re, im;
} Complex;
#define N 2
#define M 2
int main()
{
Complex* p;
Complex matrix[N][M]; //already filled
Complex m[N*M];
int n;
n = 0;
p = NULL;
for(p = &matrix[0][0]; p<= &matrix[0][0]+N*M-1; p++)
{
m[n] = *p;
n = n+1;
}
}

You can use standard C function memcpy declared in header <string.h> for example
memcpy( m, matrix, N * M * sizeof( Complex ) );
If you want to use a loop that uses pointers then it can look for example the following way
for ( Complex *q = ( Complex * )matrix, *p = m; q != ( Complex * )matrix + N * M; p++, q++ )
{
*p = *q;
}

I've modified your program to initialize the matrix array, and to print to stdout the values of matrix and the array m after the copy using the for loop:
#include <stdio.h>
typedef struct
{
float re, im;
} Complex;
#define N 2
#define M 2
int main()
{
Complex* p;
Complex matrix[N][M]; //already filled
Complex m[N*M];
int idx, jdx, val = 1;
for (idx = 0; idx < N; idx++) {
for (jdx = 0; jdx < M; jdx++) {
matrix[idx][jdx].re = val;
matrix[idx][jdx].im = val;
++val;
}
}
int n;
n = 0;
p = NULL;
for (p = &matrix[0][0]; p < &matrix[0][0] + N*M; p++)
{
printf("matrix[%d] = %f + %fi\n", n, p->re, p->im);
m[n] = *p;
n = n+1;
}
int midx = 0;
for (midx = 0; midx < N*M; midx++) {
printf("m[%d] = %f + %fi\n", midx, m[midx].re, m[midx].im);
}
return 0;
}
I'm not sure what happened but to me it just looks like you didn't initialize the arrays. Remember, memcpy is your friend. Hope this code helps.

I think the pointer p holds the address of a struct Complex. Not sure but try once like this
for(p = &matrix[0][0]; p<= &matrix[0][0]+N*M-1; p = p + sizeof(int))
{
m[n] = *p;
n = n+1;
}
}

The fastest way to do the copy is with memcpy, but if you want to use a loop, the code should look like this
Complex matrix[N][M];
Complex array[N*M];
Complex *p = array;
for ( int n = 0; n < N; n++ )
for ( int m = 0; m < M; m++ )
*p++ = matrix[n][m];
In response to the comment, given only a pointer to the matrix, and knowing the dimensions, it's possible to create a pointer that acts like a two dimensional array.
void someFunction( Complex *matrix, int sizeN, int sizeM )
{
Complex (*p)[sizeM] = (void *)matrix;
for ( int n = 0; n < sizeN; n++ )
for ( int m = 0; m < sizeM; m++ )
printf( "%f %f\n", p[n][m].re, p[n][m].im );
}

Related

Recursive selection sort error 11 when ordering big integers

I have to use the recursive selection sort in order to order different arrays of integers.
These arrays are respectively formed by 100, 1000, 10000, 100000, 200000, 500000 items and can be formed by ordered numbers, partially ordered numbers, inverted ordered numbers and random numbers.
After that I have to calculate the time the algorithm took to order the array.
I have to use recursion, It's a homework.
I created a function that generates the array:
typedef enum {ORINATO, INVERS, PARZ_ORDINATO, RANDOM} Ordine;
int *generaArray(int dimensione, Ordine ordine) {
int i, j, n;
int *array = (int*)malloc(dimensione * sizeof(int));
if (!array){
return NULL;
}
switch (ordine){
case ORINATO:
for (i = 0; i < dimensione; i++){
array[i] = i;
} break;
case INVERS:
n =0;
for ( i = dimensione-1; i >= 0 ; i--) {
array[i] = n;
n++;
}break;
case PARZ_ORDINATO:
for (i = 0; i < dimensione/2 ; i++) {
array[i] = i;
}
for (j = i+1; j <dimensione; j++){
n = rand();
array[j] = n;
};break;
case RANDOM:
for ( i = 0; i <= dimensione ; i++) {
array[i] = rand();
}break;
default:
break;
}
return array;
}
And it works like wonders.
Then I have created the recursive selection sort like follows:
void recursiveSelectionSort(int *array, int dim, int start){
int min=0;
if (start >= dim-1){
return;
}
min = findMin(array, start, start+1, dim);
swap(&array[min], &array[start]);
recursiveSelectionSort(array, dim, start+1);
}
int findMin(int *array, int min, int start, int dim){
if(start == dim ){
return min;
}
if (array[start]< array[min]){
min = start;
}
return findMin(array, min, start+1, dim);
}
void swap (int* x, int *y){
int temp = *x;
x = *y;
y = *temp;
}
Now, this as well should work but something clearly isn't. Let's make an example with the implementation, this is what i put in my main:
int main() {
int *array;
clock_t start, end;
double t;
array = generaArray(1000, ORINATO);
start = clock();
recursiveSelectionSort(array, 1000, 0);
end = clock();
t = ((double) (end - start)) / CLOCKS_PER_SEC;
printf("\nIl tempo impiegato per 1000 elementi รจ: %lf secondi", t);
return 0;
}
This works (but it's slower thank it should be). However if you try and change the dimension from 1000 to 200000 or 500000 it shows error 11.
What is it causing it? I tried everything but it doesn't seem to work.
For starters recursive functions called for large arrays can invoke a stack overflow.
So use non-recursive functions that implement the method selection sort for large arrays.
As for your implementation then for example the function swap has typos.
void swap (int* x, int *y){
int temp = *x;
x = *y;
y = *temp;
}
I think you mean
void swap (int* x, int *y){
int temp = *x;
*x = *y;
*y = temp;
}
All other functions have too many parameters.
For example the function findMin can be declared the following way
size_t findMin( const int *a, size_t n );
and can be also defined as a recursive function (if you decided to write recursive functions then this function can be also recursive)
Here is a demonstrative program that shows how the functions can be defined
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void swap( int *x, int *y )
{
int temp = *x;
*x = *y;
*y = temp;
}
size_t findMin( const int a[], size_t n )
{
if ( n < 2 )
{
return 0;
}
else
{
size_t i = findMin( a + 1, n - 1 ) + 1;
return a[i] < a[0] ? i : 0;
}
}
void recursiveSelectionSort( int a[], size_t n )
{
if ( !( n < 2 ) )
{
size_t i = findMin( a + 1, n - 1 ) + 1;
if ( a[i] < a[0] ) swap( &a[0], &a[i] );
recursiveSelectionSort( a + 1, n - 1 );
}
}
int main(void)
{
enum { N = 15 };
int a[N];
srand( ( unsigned int )time( NULL ) );
for ( size_t i = 0; i < N; i++ )
{
a[i] = rand() % N;
}
for ( size_t i = 0; i < N; i++ )
{
printf( "%d ", a[i] );
}
putchar( '\n' );
recursiveSelectionSort( a, N );
for ( size_t i = 0; i < N; i++ )
{
printf( "%d ", a[i] );
}
putchar( '\n' );
return 0;
}
The program output might look like
11 9 3 5 6 8 2 4 5 3 7 9 2 0 14
0 2 2 3 3 4 5 5 6 7 8 9 9 11 14

Sorting a structure

I wanted to sort this problem in C with something like bubble sort ... anyone can help
Implement a list with 5 struct Point (Being this a point w/ X, y);
Sort the 5 struct point (first evaluate x then y).
Example:
// The points
p[0]={2,3}
p[1]={4,5}
p[2]={1,5}
p[3]={4,3}
p[4]={1,2}
// Should become
p[0]={1,2}
p[1]={1,5}
p[2]={2,3}
p[3]={4,3}
p[4]={4,5}
If you want to sort structures, you still have to break it down into comparing numeric types. With this in mind, let's take your example with the points:
struct tagPoint
{
int x;
int y;
};
typedef struct tagPoint Point;
Now, let's suppose you have an array of Point and you want it sorted. You can take two approaches:
1. Straightforward function which sorts the array:
Just make the function to sort the array:
void SortPointArray(Point* Points, unsigned int n)
{
/* This will sort the points with priority on the x and then the y value in ascending order. */
for(unsigned int i = 0; i < n-1; i++)
for(unsigned int j = i+1; j < n; j++)
{
if (Points[i].x > Points[j].x)
{
Point aux = Points[i];
Points[i] = Points[j];
Points[j] = aux;
}
else if ((Points[i].x == Points[j].x) && (Points[i].y > Points[j].y))
{
Point aux = Points[i];
Points[i] = Points[j];
Points[j] = aux;
}
}
}
2. Wrap the algorithm in a generic function and use callbacks for each type you want to sort:
This is a little more complicated, but it will save you some time if you use it frequently. Here, this function uses the same algorithm as the one above, but can sort any types.
void Sort(void* lpArray, unsigned int n, size_t cbSize, int (*Cmp)(void*, void*), void (*Swap)(void*, void*))
{
for(unsigned int i = 0; i < n-1; i++)
for(unsigned int j = i+1; j < n; j++)
/* Cast void* to char* to get rid of warning with pointer arithmetic... */
if ( Cmp( ((char*)lpArray) + i*cbSize, ((char*)lpArray) + j*cbSize) )
Swap( ((char*)lpArray) + i*cbSize, ((char*)lpArray) + j*cbSize );
}
As you can see, it requires 2 more functions passed as parameters. If you want this Sort function to know how to sort the Point array, you must define a Comparrison function and a Swapping function and tell the Sort function to use them.
Here is how i implemented them:
/** This function return 1 if p1 should be swapped with p2. */
int ComparePoints(void* vp1, void* vp2)
{
Point *p1, *p2;
p1 = vp1;
p2 = vp2;
if (p1->x > p2->x)
return 1;
else if ((p1->x == p2->x) && (p1->y > p2->y))
return 1;
return 0;
}
/** This will swap 2 points. */
void SwapPoints(void* vp1, void* vp2)
{
Point p = *(Point*)vp1;
*(Point*)vp1 = *(Point*)vp2;
*(Point*)vp2 = p;
}
How do you use them?
If you only want to use the first SortPointArray function, this is enough:
int main()
{
Point Array[10];
/* Read the points. */
for(unsigned int i = 0; i < 10; i++)
scanf("%d %d", &Array[i].x, &Array[i].y);
SortPointArray(Array, 10);
/*Print the points.*/
for(unsigned int i = 0; i < 10; i++)
printf("%d %d\n", Array[i].x, Array[i].y);
return 0;
}
But if you want to use the generic Sort function (which i recommend only if you have multiple types you want to sort like Points, Lines etc) you have to define the two callbacks (ComparePoints and SwapPoints)
int main()
{
Point Array[10];
/* Read the points. */
for(unsigned int i = 0; i < 10; i++)
scanf("%d %d", &Array[i].x, &Array[i].y);
Sort(Array, 10, sizeof(Point), ComparePoints, SwapPoints);
/*Print the points.*/
for(unsigned int i = 0; i < 10; i++)
printf("%d %d\n", Array[i].x, Array[i].y);
return 0;
}
The OP is asking for a C solution, so here you go:
void bsortDesc(struct yourStruct list[80], int s)
{
int i, j;
struct yourStruct temp;
for (i = 0; i < s - 1; i++)
{
for (j = 0; j < (s - 1-i); j++)
{
if (list[j].marks < list[j + 1].marks)
{
temp = list[j];
list[j] = list[j + 1];
list[j + 1] = temp;
}
}
}
}
Also, here's what I got it from: here.

Direct sum of matrix function

This struct allows representing arbitrary size matrices, where M is the number of rows, N is the number of columns and data is a pointer to M*N values of type double stored by rows.
struct matrix {
size_t M, N;
double *data;
};
struct matrix *mat_directsum(const struct matrix *a, const struct matrix *b);
The function mat_directsum accepts two pointers to arrays as a parameter and should return to the direct sum, dynamically allocated on the heap.
Example:
A.M = 2
A.N = 3
A.data = (1, 1, 2, 0, 1, -3)
Example of direct sum function
I just need a few tips on how to set the function, just to see how others work with arrays of this type, because the only way that comes to mind is an iterative methods with many loops, however, it is enough work long and ingenious, I would like to know if there are easier method to solve it. Thank you
ps.
(memory allocation is not a problem of course)
EDIT
I solved like that:
struct matrix *mat_directsum(const struct matrix *a, const struct matrix *b) {
struct matrix *c = malloc(sizeof(struct matrix));
c->M = a->M + b->M;
c->N = a->N + b->N;
int n = c->M * c->M;
double *dati = calloc(n, sizeof(double));
int t = 0;//index new array
int y = 0;//index first mat
int z = 0;//index second mat
for (int i = 0; i < c->N; i++) {
if (i < a->N) {//first mat
for (int j = 0; j < c->M; j++) {
if (j < a->M) {
dati[t] = a->data[y];
y++;
}
t++;
}
} else {//second mat
for (int j = 0; j < c->M; j++) {
if (j >= a->M) {
dati[t] = b->data[z];
z++;
}
t++;
}
}
}
c->data = dati;
return c;
}
I don't know how to do it which only one for loop
//macro which will point to an element indexed at [xe][ye]
#define ELEMENT(data,rows,columns,xe,ye) (data+((xe)*(columns)+(ye)))
struct matrix
{
size_t M, N;
double *data;
};
//won't mind changing the return type from "struct matrix*" to "struct matrix"
struct matrix mat_directsum(const struct matrix *a, const struct matrix *b)
{
int x;
struct matrix res;
res.M = a->M + b->M;
res.N = a->N + b->N;
//using calloc will set the memory to zero i.e all the bytes will be set to zero.
res.data = (double*)calloc(res.M * res.N, sizeof(double));
if(res.data == NULL)
{
return res;
}
for(x = 0; x < a->M; ++x)
{
memcpy(ELEMENT(res.data, res.M, res.N, x, 0), ELEMENT(a->data, a->M, a->N, x, 0), a->N * sizeof(double));
}
for(x = 0; x < b->M; ++x)
{
//note the offset by [a->M][a->N] while accessing elements of res.
memcpy(ELEMENT(res.data, res.M, res.N, x + a->M, a->N), ELEMENT(b->data, b->M, b->N, x, 0), b->N * sizeof(double));
}
return res;
}
struct matrix res = mat_directsum(&a, &b);
if(res.data != NULL)
{
free(res.data);
}
Besides the error n = c->M * c->M, spotted by M.M (what a coincidence of Ms!), your solution has another error in the for loops: You confused the row and column numbers M and N - since the values are stored by rows, the outer loop has to be for (int i = 0; i < c->M; i++) and the inner loops have to be for (int j = 0; j < c->N; j++), so all M and N in those loops (also in the ifs) have to be swapped. Apart from that and the missing allocation error checks, your solution is fine.
I don't know how to do it which only one for loop
If you want to see an alternative approach, here's one with a helper function to insert the matrices into the sum matrix:
#include <string.h>
void mat_insert(const struct matrix *s, struct matrix *d, int r, int c)
{ // copy source matrix s to destination matrix d at row r, column c
for (int i = 0; i < s->M; i++) // for each row
memcpy(d->data+(r+i)*d->N+c, s->data+i*s->N, s->N*sizeof*s->data);
}
struct matrix *mat_directsum(const struct matrix *a, const struct matrix *b)
{
struct matrix *c = malloc(sizeof *c); if (!c) return NULL;
c->M = a->M + b->M;
c->N = a->N + b->N;
int n = c->M * c->N;
c->data = calloc(n, sizeof *c->data); if (!c->data) return free(c), NULL;
mat_insert(a, c, 0, 0); // copy a to c at row 0, column 0
mat_insert(b, c, a->M, a->N); // copy b to c at row a->M, column a->N
return c;
}

How can I create a function for dynamic allocation for 2d array in c? [duplicate]

This question already has answers here:
Allocate memory 2d array in function C
(8 answers)
C. Segmentation Fault when function modifies dynamically allocated 2d array
(3 answers)
Closed 8 years ago.
#include<stdio.h>
#include<stdlib.h>
void aloc_dinamic(double **M)
{
int i;
M = (double **)malloc(m*sizeof(double *));
for(i=0;i<m;i++)
M[i] = (double *)calloc(m, sizeof(double));
}
int main(void)
{
double **H;
aloc_dinamic(H)
}
How can I create a function for dynamic allocation for 2d array in c?
I tried this, but it doesn't work.
#include <stdlib.h>
double ** aloc_dynamic( size_t n, size_t m )
{
double **p = ( double ** )malloc( n * sizeof( double * ) );
for ( size_t i = 0; i < n; i++ )
{
p[i] = ( double * )malloc( m * sizeof( double ) );
}
return p;
}
int main(void)
{
size_t n = 5;
size_t m = 10;
double **p = aloc_dynamic( n, m );
// before exiting the function free the allocated memory
}
... and with the corresponding free function
#include<stdio.h>
#include<stdlib.h>
double** alloc_2d(int y_extent, int x_extent)
{
int y, x;
double ** array = (double**)malloc(y_extent * sizeof(double*));
for (y = 0 ; y < y_extent ; ++y) {
array[y] = (double*)malloc(sizeof(double) * x_extent);
for(x = 0 ; x < x_extent ; ++x) {
array[y][x] = 0.0;
}
}
return array;
}
void free_2d(double** array, int y_extent)
{
int y;
for(y = 0 ; y < y_extent ; ++y) {
free(array[y]);
}
free(array);
}
int main(void)
{
double **H = alloc_2d(50,100);
H[10][10] = 0.0; // for example
free_2d(H, 50);
return 0;
}
You can do it like this:
// We return the pointer
int **get(int N, int M) /* Allocate the array */
{
/* Check if allocation succeeded. (check for NULL pointer) */
int i, **table;
table = malloc(N*sizeof(int *));
for(i = 0 ; i < N ; i++)
table[i] = malloc( M*sizeof(int) );
return table;
}
// We don't return the pointer
void getNoReturn(int*** table, int N, int M) {
/* Check if allocation succeeded. (check for NULL pointer) */
int i;
*table = malloc(N*sizeof(int *));
for(i = 0 ; i < N ; i++)
*table[i] = malloc( M*sizeof(int) );
}
void fill(int** p, int N, int M) {
int i, j;
for(i = 0 ; i < N ; i++)
for(j = 0 ; j < M ; j++)
p[i][j] = j;
}
void print(int** p, int N, int M) {
int i, j;
for(i = 0 ; i < N ; i++)
for(j = 0 ; j < M ; j++)
printf("array[%d][%d] = %d\n", i, j, p[i][j]);
}
void free2Darray(int** p, int N) {
int i;
for(i = 0 ; i < N ; i++)
free(p[i]);
free(p);
}
int main(void)
{
int **p;
//getNoReturn(&p, 2, 5);
p = get(2, 5);
fill(p ,2, 5);
print(p, 2, 5);
free2Darray(p ,2);
return 0;
}
Remember a 2D array is a 1D array of pointers, where every pointer, is set to another 1D array of the actual data.
Image:
I suggest you to read the explanation here.

2D pointer arithmetic in C

I am attempting to swap 2 elements in a 2D array in C, with no luck.
Thanks for the answers so far, but I have edited this code to make things clearer about what I am doing.
typedef struct smystruct { /* stuff... */ } mystruct;
void nswap( mystruct ** a, mystruct ** b )
{
mystruct * tmp = *a;
*a = *b;
*b = tmp;
}
void nqsort( mystruct ** h, int m, int n )
{
double key = 0.0;
int i = 0, j = 0, k = 0;
if( m < n ) {
// choose the pivot point...
k = (m + n) / 2;
nswap( &h[ n ], &h[ k ] );
key = (*h+m)->prob;
i = m + 1;
j = n;
while ( i <= j ) {
while ( (i <= n) && (*h+i)->prob <= key )
i++;
while ( (j >= m) && (*h+j)->prob > key )
j--;
if ( i < j ) {
nswap( &h[i], &h[j] );
}
}
// swap two elements
nswap( &h[m], &h[j] );
// recursively sort the lesser list
nqsort( h, m, j-1 );
nqsort( h, j+1, n );
}
}
int main()
{
mystruct * p = NULL;
// get the number of nodes (m)...
fscanf( in, "%d", &m );
// allocate memory for the node and connectivity matrix arrays...
p = (mystruct*)malloc( sizeof( mystruct ) * m );
// read in the location and associated probabilities!...
for ( ; loop < m ; ++loop ) {
mystruct * tmpnode = p + loop;
tmpnode->str = (char*)malloc( sizeof( char ) * 1024 );
fscanf( in, "%s %lf", (char *)tmpnode->str, &tmpnode->prob );
}
nqsort( &p, 0, m );
}
Needless to say this does not work. I have searched for examples and nothing seems to work. Advise for the n00b would be appreciated.
The last element has index count-1, not count.
h[0] h[1] h[2] h[3] h[4] h[5] h[6] h[7] h[8] h[9]
----------------------------------------------------------
total 10 elements
I don't know what is fwnodes, perhaps you mean h.
Multiple stuff is wrong there.
1/ Your 2D array is badly allocated (or code is missing).
2/ A proper way to do such 2D allocation is to use Iliffe pointer (as advised in Numrical Recipes in C/C++).
mystruct** alloc_array( int h, int w )
{
int i;
mystruct** m = malloc(h*sizeof(mystruct*));
m[0] = malloc(h*w*sizeof(mystruct));
for(i=1;i<h;i++) m[i] = m[i-1]+w;
return m;
}
void release_array(mystruct** m)
{
free( m[0] );
free( m);
}
This way of allocating brings you both a contiguous block of memory (which is easier to handle, is more cache friendly, dont require to do some index computation) and a [][] access.
Your swap function then become :
void swap( mystruct* a, mystruct* b )
{
mystruct tmp = *a
*a = *b;
*b = tmp;
}
and can be called like :
swap( &some_tab[i][j], &some_other_tab[u][v] );
In a full example :
int main()
{
mystruct** my_array = alloc_array(3,4); /* 3x4 mystruct array */
/* fill the array */
/* Swap some */
swap( &my_array[2][1], &my_array[0][3] );
release_array(my_array);
}
You are passing pointer to array to your function. That means h has only one element.
swap( &p, 10 );
Should be:
swap( p, 10 );
That means you need to change your function to accept arrays of mystruct or change p to array of pointers to mystruct.
And, as KennyTM suggested the last element has index 9 not 10.

Resources