In a block of memory, treatead as two segments, A and B,
i set up pointers in segment A such that values from
segment B can be viewed as matrices and accessed by indices:
float **matrix = ( ( void ** ) view->data[ i ] )[ j ];
After allocating memory and assigning the pointers i then set all the
values for a specific matrix.
However, when trying to print individual values of that matrix,
the program seg-faults due to an invalid read.
If i dont't call the set_weights function, values are printed
fine ( and valgrind reports no leaks ). So i assume that trying
to set values has an unwanted side effect of messing up pointers.
I would like to understand if the error is in the pointer assignments
or on access.
Pease have a look and help me.
Regards,
Alfred
[ OS: x86_64 debian linux, gcc 4.2.9 ]
#include <assert.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
enum { Weight, Delta, Max };
typedef struct {
void **data;
} View;
void matrix_2D_print( int x, int y, float **values ) {
int i, j;
for( i = 0; i < x; ++i ) {
for( j = 0; j < y; ++j ) {
printf( "\t\t%f", values[ i ][ j ] ); // Invalid read
if( j < ( y - 1 ) ) {
printf( ", " );
}
}
printf( "\n" );
}
}
void set_weights( int layers, int x, int y, View *view ) {
int i, j, l;
void **view_ptr = view->data[ Weight ];
for( l = 0; l < layers; ++l ) {
float **m2_data = view_ptr[ l ];
for( i = 0; i < x; ++i ) {
for( j = 0; j < y; ++j ) {
m2_data[ i ][ j ] = 0.27f;
}
}
}
}
int main( int argc, char **argv ) {
int i, l, m;
int x = 3;
int y = 2;
int layers = 2;
size_t step_view = Max * sizeof( void ** );
size_t len_step_view = x * sizeof( void ** );
size_t len_segment_A = step_view + x * layers * Max * sizeof( void ** );
size_t len_segment_B = x * y * layers * Max * sizeof( float );
char *storage = calloc( 1, len_segment_A + len_segment_B );
float *segment_b = ( float * )( storage + len_segment_A );
View view;
view.data = ( void ** ) storage;
for( m = 0; m < Max; ++m ) {
void **segment_a = ( void ** )( storage + step_view );
view.data[ m ] = segment_a;
for( l = 0; l < layers; ++l ) {
segment_a[ l ] = segment_b;
void **cur = segment_a[ l ];
for( i = 0; i < x; ++i ) {
cur[ i ] = segment_b;
segment_b += y;
}
step_view += len_step_view;
}
}
assert( len_segment_A == step_view );
set_weights( layers, x, y, &view );
void **view_ptr = view.data[ Weight ];
printf( "\tLayer: %d\n", 0 );
matrix_2D_print( x, y, view_ptr[ 0 ] );
free( storage );
return 0;
}
Related
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
I have a problem to exchange the values of an index in a 2D array by using a pointer. My code for example has an two dimensional array with the initialization {{1,2},{2,3},{3,4},{4,5}} and I want to exchange the values of two indexes in the 2D array. I created a function named swap like this:
void swap(double points[20][2],int i, int j){
double *a,*b;
a= *(*(points +i)+ 0;
*(*(points +i)+ 0 = points[j][0];
*(*(points +j)+ 0 = a;
b= *(*(points +i)+ 1;
*(*(points +i)+ 1 = points[j][1];
*(*(points +j)+ 1 = a;
}
i,j here mean I want to change index i to j and vice-versa so for example when I used swap(points,0,1) the 2D array points will change like this: {{2,3},{1,2},{3,4},{4,5}}
Any help would appreciated.
You can treat 2D array as a pointer to 1D arrays, and do a swap using a temporary array, like this:
void swap(double points[20][2],int i, int j) {
double tmp[2];
memcpy(tmp, points+i, sizeof(*points));
memcpy(points+i, points+j, sizeof(*points));
memcpy(points+j, tmp, sizeof(*points));
}
demo
The implementation is the classic swap, i.e.
tmp = points[i];
points[i] = points[j];
points[j] = tmp;
but since arrays in C cannot be assigned as a unit, memcpy is used instead.
Here you are
void swap( double points[][2], size_t i, size_t j )
{
double ( *a )[2] = points + i;
double ( *b )[2] = points + j;
for ( size_t i = 0; i < 2; i++ )
{
double tmp = ( *a )[i];
( *a )[i] = ( *b )[i];
( *b )[i] = tmp;
}
}
Or entirely without the subscript operator
void swap( double points[][2], size_t i, size_t j )
{
double ( *a )[2] = points + i;
double ( *b )[2] = points + j;
for ( size_t i = 0; i < 2; i++ )
{
double tmp = *( *a + i );
*( *a + i ) = *( *b + i );
*( *b + i ) = tmp;
}
}
Here is a demonstrative program
#include <stdio.h>
#define N 2
void swap( double points[][N], size_t i, size_t j )
{
double ( *a )[N] = points + i;
double ( *b )[N] = points + j;
for ( size_t i = 0; i < N; i++ )
{
double tmp = *( *a + i );
*( *a + i ) = *( *b + i );
*( *b + i ) = tmp;
}
}
int main(void)
{
double points[][N] =
{
{ 1, 2 }, { 2, 3 }, { 3, 4 }, { 4, 5 }
};
const size_t M = sizeof( points ) / sizeof( *points );
for ( size_t i = 0; i < M; i++ )
{
printf( "{ %.1f, %.1f } ", points[i][0], points[i][1] );
}
putchar( '\n' );
swap( points, 0, 1 );
for ( size_t i = 0; i < M; i++ )
{
printf( "{ %.1f, %.1f } ", points[i][0], points[i][1] );
}
putchar( '\n' );
return 0;
}
The program output is
{ 1.0, 2.0 } { 2.0, 3.0 } { 3.0, 4.0 } { 4.0, 5.0 }
{ 2.0, 3.0 } { 1.0, 2.0 } { 3.0, 4.0 } { 4.0, 5.0 }
I'm trying to implement a bucket sort using a resizable vector function that I made. The vector works fine, but I get a segmentation fault anytime I try to run my sort function. Can anyone help me remedy this?
Notes about code: K=# of buckets in this case 10. find_max and find_min do exactly what you'd expect. vector_int_construct initializes an array and vector_int_push_back pushes integers to the end of the array. vector_int_sort just calls on a merge_sort function I created that also works fine on its own.
typedef struct {
size_t size;
size_t maxsize;
int* array;
}
vector_int_t;
void bucket_sort( int* a, size_t size )
{
int min = find_min( a, size );
int max = find_max( a, size );
size_t range = (( max - min ) / K );
vector_int_t buckets[K];
for( size_t i = 0; i < K; i++ ) {
vector_int_construct( &buckets[i] );
for( size_t j = 0; j < range; j++ ) {
vector_int_push_back( &buckets[i], a[j] );
}
}
for( size_t i = 0; i < K; i++ ) {
vector_int_sort( &buckets[i] );
}
size_t cnt = 0;
while( cnt != size ) {
for( size_t i = 0; i < K; i++ ) {
for( size_t j = 0; j < vector_int_size( &buckets[i] ); j++ ) {
a[cnt] = buckets[i].array[j];
cnt++;
}
}
}
}
int main()
{
size_t size = 4;
int a[] = { 19, 95, 4, 23 };
// Print out array before
printf( "Before sorting: " );
ece2400_print_array( a, size );
// Call sort
bucket_sort( a, size );
// Print out array after
printf( "After sorting: " );
ece2400_print_array( a, size );
return 0;
}
I can't get it work!
Throws seg fault.
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
size_t NbOfElmts;
float * Weights;
int * Areas;
} ListOfCoeff;
typedef struct
{
size_t NbOfElmts;
ListOfCoeff * Elmts;
} SetOfListsOfCoeff;
int main( int argc, const char* argv[] ){
SetOfListsOfCoeff * theList;
int N = 10;
float *A = malloc( N * sizeof(*A) );
for ( int i = 0; i < N; i++)
A[ i ] = i;
for ( int i = 0; i < N; i++ )
( (theList[ i ].Elmts)->Weights)[ i ] = A[ i ];
for ( int i = 0; i < N; i++)
printf("\n List = %f", ( (theList[ i ].Elmts)->Weights)[ i ] );
return 0;
}
The problem in the line:
( (theList[ i ].Elmts)->Weights)[ i ] = A[ i ];
You have not allocated any memory for theList.
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.