any body knows how to convert 2d dynamic array to static so that i can use it in lapacke. dgels function which only take static matrix in c?
when i use malloc it does not give correct answer. how can i use malloc so that it works with it.thankyou
#include <stdio.h>
#include <lapacke.h>
#include <conio.h>
int main (int argc, const char * argv[])
{
/*double a[5][3] = {1,1,1,2,3,4,3,5,2,4,2,5,5,4,3};*/
double b[5][2] = {-10,-3,12,14,14,12,16,16,18,16};
lapack_int info,m,n,lda,ldb,nrhs;
int i,j;
double **a;
a=(double**)malloc(5* sizeof(double*));
for (i=0;i<5;i++)
{
a[i]=(double*)malloc(3* sizeof(double));
}
a[0][0]=1;
a[0][1]=1;
a[0][2]=1;
a[1][0]=2;
a[1][1]=3;
a[1][2]=4;
a[2][0]=3;
a[2][1]=5;
a[2][2]=2;
a[3][0]=4;
a[3][1]=2;
a[3][2]=5;
a[4][0]=5;
a[4][1]=4;
a[4][2]=3;
m = 5;
n = 3;
nrhs = 2;
lda = 3;
ldb = 2;
info = LAPACKE_dgels(LAPACK_ROW_MAJOR,'N',m,n,nrhs,*a,lda,*b,ldb);
for(i=0;i<n;i++)
{
for(j=0;j<nrhs;j++)
{
printf("%lf ",b[i][j]);
}
printf("\n");
}
getch();
return(info);
}
I do not know lapacke.dgels but try to change:
double **a;
a=(double**)malloc(5* sizeof(double*));
for (i=0;i<5;i++)
{
a[i]=(double*)malloc(3* sizeof(double));
}
to:
double (*a)[3];
a = malloc(5 * 3 * sizeof(double));
a is not a 2d array, it is an array of pointers to separate 1d arrays. Passing *a to LAPACKE_dgels only gives it a pointer to the first row. It will have no way to know where all of the other rows were allocated since they were allocated independently. It wants the entire array to be in a single contiguous block of memory. a must be of type double*, not double**, and you don't dereference it when passing it. You must flatten the 2d indexes into 1d indexes yourself, using either row or column major form (which you tell the function).
EDIT
The following code allocates a flat 1d array with room for m*n doubles. It then fills the array by converting the 2d indices to 1d row-major indices using the formula row * n + col. If we wanted column-major indices, we would use col * m + row.
#include <stdio.h>
#include <lapacke.h>
#include <conio.h>
int main (int argc, const char * argv[])
{
double b[5][2] = {-10,-3,12,14,14,12,16,16,18,16};
lapack_int info,m,n,lda,ldb,nrhs;
int i,j;
double *a;
m = 5;
n = 3;
nrhs = 2;
lda = 3;
ldb = 2;
a = malloc(m * n * sizeof(double));
a[0 * n + 0] = 1;
a[0 * n + 1] = 1;
a[0 * n + 2] = 1;
a[1 * n + 0] = 2;
a[1 * n + 1] = 3;
a[1 * n + 2] = 4;
a[2 * n + 0] = 3;
a[2 * n + 1] = 5;
a[2 * n + 2] = 2;
a[3 * n + 0] = 4;
a[3 * n + 1] = 2;
a[3 * n + 2] = 5;
a[4 * n + 0] = 5;
a[4 * n + 1] = 4;
a[4 * n + 2] = 3;
info = LAPACKE_dgels(LAPACK_ROW_MAJOR,'N',m,n,nrhs,a,lda,*b,ldb);
for(i=0;i<n;i++)
{
for(j=0;j<nrhs;j++)
{
printf("%lf ",b[i][j]);
}
printf("\n");
}
getch();
return(info);
}
Related
apologies if this has appeared elsewhere, I've not been able to find a clear answer.
I've been using Ed S's answer, Option 1 (linked below) to allocate memory, populate the array, then return it back to the caller.
He recommends freeing the memory after you've finished with it, however when I added the free() line, I get a core dump.
I've had a poke around with GDB, but my skills probably aren't what the need to be.
Thanks in advance for any help you can give.
Link to answer: Returning an array using C
Code:
#include <stdio.h>
#include <stdlib.h>
char * createArray();
int main(int argc, char *argv[]){
printf("Creating Array...\n");
// pointer to an int
char *p;
// size of the array
int i,j;
// width of array
int width = 7;
// height of array
int height = 5;
// get an array from the function
p = createArray(width, height);
// check if p was created properly
if (p){
// print out the array
for (i = 0; i < width; ++i){
for (j = 0; j < height; ++j){
printf("[%c] ", *(p + (i * width) + j));
}
printf("\n");
}
// here's where it hits the fan
free(p);
}
return 0;
}
char * createArray(int w, int h){
// allocate some memory for the array
char *r = malloc(w * h * sizeof(char));
// check if the memory allocation was successful
if(!r){
return NULL;
}
int i, j;
int count = 0;
for (i = 0; i < w; ++i){
for (j = 0; j < h; ++j){
*(r + (i * w) + j) = 'X';
++count;
}
}
return r;
}
With this
char *r = malloc(w * h * sizeof(char));
You allocate w * h (7 * 5 = 35 bytes) of memory. But
*(r + (i * w) + j) = 'X';
can access well beyond the 35 bytes you have allocated (you'll see if you test the possible values for i * w + j in the loop), resulting in undefined behaviour.
This possibly overwrites the malloc's internal data structures and thus you happen to get core dump when you free().
You made a mistake on these lines
*(r + (i * w) + j) = 'X';
and
printf("[%c] ", *(p + (i * width) + j));
To keep inside the boundaries of your "2D" array -it's one dimensional but you are working around it like a compiler would-it should be i * length in there:
*(r + (i * h) + j) = 'X';`
and
printf("[%c] ", *(p + (i * height) + j)); `
If you use this, you should be able to stay within the boundaries without making a mess.
I need to create a struct that holds a 2D array however the array size can vary so i cannot define it with a constant length. I tried to solve this with a double pointer only to find out the double pointer is not the same as a double array. So how can i do this?
struct GaussianKernel {
int r;
double weightSum;
double **kernel;
};
GaussianKernel initializeKernel2D(jdouble sigma){
int r = (int) ceil(3 * sigma);
int kernelLen = 2 * r + 1;
double G[kernelLen][kernelLen];
double weightSum = 0;
double temp;
for (int y = -r; y <= r; y++)
{
for (int x = -r; x <= r; x++)
{
temp = exp(-(pow(x, 2) + pow(y, 2)) / (2 * pow(sigma, 2))) / (2 * PI * pow(sigma, 2));
G[y + r][x + r] = temp;
weightSum = weightSum + temp;
}
}
struct GaussianKernel GKernel;
GKernel.r = r;
GKernel.kernel = G;
GKernel.weightSum = weightSum;
return GKernel;
}
YOu should allocate your 2D dynamic array as:
GKernel.kernel = malloc(kernelLen * sizeof(double *));
for(i=0;i<kernelLen;i++)
GKernel.kernel[i] = malloc(kernelLen * sizeof(double));
Then you can store values in GKernel.kernel as per logic of your program
I know how to do a potentioal non-contiguous array in the following way:
int main () {
int ***array = (int***)malloc(3*sizeof(int**));
int i, j;
for (i = 0; i < 3; i++) {
// Assign to array[i], not *array[i] (that would dereference an uninitialized pointer)
array[i] = (int**)malloc(3*sizeof(int*));
for (j = 0; j < 3; j++) {
array[i][j] = (int*)malloc(3*sizeof(int));
}
}
array[1][2][1] = 10;
return 0;
}
with the code above, the array[0][j] blocks can be not contiguous. To get contiguous, I feel that we need to malloc in this way
int* array = (int*)malloc(3*3*3*sizeof(int));
int** y = (int**)malloc(3*3*sizeof(int**));
int*** x = (int***)malloc(3*sizeof(int***));
for(i = 0; i < 3; i++)
{
vals = vals + i*m*n;
x[i] = &vals;
for(j = 0; j < 3; j++)
{
x[i][j] = vals + j * n;
}
}
However, I got troulbe with address assignment. I am not a c programmer, can anyone correct my fault? Thanks in advance...
int*** x = (int***)malloc(3*sizeof(int***));
should be
int*** x = (int***)malloc(3*sizeof(int**));
Now initialization can be :
for(i = 0; i < 3; i++)
{
x[i] = y + 3*i;
for(j = 0; j < 3; j++)
{
x[i][j] = array + i*3*3 + j*3;
}
}
So that x[0] points to the first element of y, x[1] to the fourth, etc.
And x[0][0]=y[0] to the first of array, x[0][1]=y[1] to the fourth of array, etc.
To allocate a contiguous 3D array, you only need to do the following (assumes all dimensions are known at compile time):
#define D0 ...
#define D1 ...
#define D2 ...
...
T (*arr)[D1][D2] = malloc( sizeof *arr * D0 ); // for any type T
...
arr[i][j][k] = some_value();
...
arr is declared as a pointer to a D1xD2 array. We then allocate enough space for D0 such arrays (sizeof *arr == sizeof (T [D1][D2])).
With this method, all of the memory for the array is allocated contiguously. Also, you only need one call to free to deallocate the whole thing.
If your dimensions are not known until runtime and you're using a C99 compiler or a C2011 compiler that supports variable-length arrays, you're still in luck:
size_t d0, d1, d2;
...
T (*arr)[d1][d2] = malloc( sizeof *arr * d0 );
The main issue is how to pass this as an argument to a function. Assuming that D1 and D2 are known at compile time, if you decide to pass it as
foo( arr, D0 );
then the prototype for foo will need to be
void foo( T (*aptr)[D1][D2], size_t n )
{
...
aptr[i][j][k] = ...;
}
and it will only be useful for n x D1 x D2-sized arrays.
If you go the VLA route, you'll need to declare the dimensions and pass values for them as well:
void foo( size_t d0, size_t d1, size_t d2, T (*aptr)[d1][d2] ) // d1 and d2 *must* be
// declared before aptr
{
...
arr[i][j][k] = some_value();
}
void bar( void )
{
size_t d0, d1, d2;
...
T (*arr)[d1][d2] = malloc( sizeof *arr * d0 );
...
foo( d0, d1, d2, arr );
...
}
If you don't have a compiler that supports VLAs, but you still want to allocate this memory contiguously, then you'll have to go the old-fashioned route - allocate it as a 1D array and compute your offsets manually:
T *arr = malloc( sizeof *arr * d0 * d1 * d2 );
...
arr[i * d0 * d1 + j * d1 + k] = some_value();
I am using some pretty neat methods for allocating multi-dimensional arrays with row pointers. The functions multi_malloc and multi_free can be used for arrays with arbitrary dimensions and arbitrary types and they work on basically all platforms and from C and C++
You can allocate, e.g. a 3-dimensional array with row-pointers recursively. E.g. a 10x20x30 dimensional array
float*** data = (float***) multi_malloc(sizeof(float),3, 10,20,20);
access elements like
data[2][3][4] = 2.0;
and free everything like (data as well as row pointers)
multi_free(data,3);
The header, which I think should be part of C is
#pragma once
#include <stdlib.h>
#include <stddef.h>
#include <stdarg.h>
#include <string.h>
#if (defined(_MSC_VER) && defined(_WIN32))
// Note when used inside a namespace, the static is superfluous
# define STATIC_INLINE_BEGIN static inline //__forceinline
# define STATIC_INLINE_END
#elif (defined(__GNUC__))
# define STATIC_INLINE_BEGIN static inline
# if defined(__CYGWIN__)
# define STATIC_INLINE_END
# else
# define STATIC_INLINE_END __attribute__ ((always_inline))
# endif
#endif
STATIC_INLINE_BEGIN void* multi_malloc(size_t s, size_t d, ...) STATIC_INLINE_END;
STATIC_INLINE_BEGIN void multi_free(void *r, size_t d) STATIC_INLINE_END;
/**
* Allocate multi-dimensional array and establish row pointers
*
* #param s size of each element
* #param d number of dimension
*
* #return
*/
STATIC_INLINE_BEGIN void* multi_malloc(size_t s, size_t d, ...) {
char* tree;
va_list ap; /* varargs list traverser */
size_t max, /* size of array to be declared */
*q; /* pointer to dimension list */
char **r, /* pointer to beginning of the array of the
* pointers for a dimension */
**s1, *t; /* base pointer to beginning of first array */
size_t i, j; /* loop counters */
size_t *d1; /* dimension list */
va_start(ap,d);
d1 = (size_t *) malloc(d*sizeof(size_t));
for(i=0;i<d;i++)
d1[i] = va_arg(ap,size_t);
r = &tree;
q = d1; /* first dimension */
if (d==1) {
max = *q;
free(d1);
return malloc(max*d);
}
max = 1;
for (i = 0; i < d - 1; i++, q++) { /* for each of the dimensions
* but the last */
max *= (*q);
r[0]=(char *)malloc(max * sizeof(char **));
r = (char **) r[0]; /* step through to beginning of next
* dimension array */
}
max *= s * (size_t) (*q); /* grab actual array memory */
r[0] = (char *)malloc(max * sizeof(char));
/*
* r is now set to point to the beginning of each array so that we can
* use it to scan down each array rather than having to go across and
* then down
*/
r = (char **) tree; /* back to the beginning of list of arrays */
q = d1; /* back to the first dimension */
max = 1;
for (i = 0; i < d - 2; i++, q++) { /* we deal with the last
* array of pointers later on */
max *= (*q); /* number of elements in this dimension */
for (j=1, s1=r+1, t=r[0]; j<max; j++) { /* scans down array for
* first and subsequent
* elements */
/* modify each of the pointers so that it points to
* the correct position (sub-array) of the next
* dimension array. s1 is the current position in the
* current array. t is the current position in the
* next array. t is incremented before s1 is, but it
* starts off one behind. *(q+1) is the dimension of
* the next array. */
*s1 = (t += sizeof (char **) * *(q + 1));
s1++;
}
r = (char **) r[0]; /* step through to begining of next
* dimension array */
}
max *= (*q); /* max is total number of elements in the
* last pointer array */
/* same as previous loop, but different size factor */
for (j = 1, s1 = r + 1, t = r[0]; j < max; j++)
*s1++ = (t += s * *(q + 1));
va_end(ap);
free(d1);
return((void *)tree); /* return base pointer */
}
/**
* Free multi-dimensional array and corresponding row pointers
*
* #param r data
* #param d number of dimensions
*/
STATIC_INLINE_BEGIN void multi_free(void *r, size_t d) {
void **p;
void *next=NULL;
size_t i;
for (p = (void **)r, i = 0; i < d; p = (void **) next,i++)
if (p != NULL) {
next = *p;
free(p);
p = NULL;
}
}
You can allocate memory for buffer of items where each item is a two dimensional array. So it is effectively is a three dimensional array:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 3
int main()
{
int (*array)[N][N] = malloc(N * N * N * sizeof(int));
/* set 0 to all values */
memset(array, 0, N * N * N * sizeof(int));
/* use as 3D array */
array[0][0][0] = 1;
array[1][1][1] = 2;
array[2][2][2] = 3;
int i;
/* print array as contiguous buffer */
for (i = 0; i < N * N * N; ++i)
printf("i: %d\n", ((int*) array)[i]);
free(array);
return 0;
}
So, in memory the array is placed as regular int array[N][N][N].
Although I think a normal array, created on the stack would be best:
int array[3][3][3];//can avoid a lot of free() calls later on
Here is a way to create a 3D array dynamically:
(I use calloc here instead of malloc as it creates initialized memory space)
int *** Create3D(int p, int c, int r)
{
int ***arr;
int x,y;
arr = calloc(p, sizeof(arr)); //memory for int
for(x = 0; x < p; x++)
{
arr[x] = calloc(c ,sizeof(arr)); //memory for pointers
for(y = 0; y < c; y++)
{
arr[x][y] = calloc(r, sizeof(int));
}
}
return arr;
}
Usage could be:
int ***array = Create3D(3,3,3);
for(i=0;i<3;i++)
for(j=0;j<3;j++)
for(k=0;k<3;k++)
array[i][j][k] = (i+1)*(j+1)*(k+1);
Note that the return of [c][m][re]alloc() is not cast in this example. Although not strictly forbidden in C, it is not recommended. (this is not the case in C++, where it is required)
Keep in mind, everything allocated, must be freed. Notice freeing is done in reverse order of allocating:
void free3D(int ***arr, int p, int c)
{
int i,j;
for(i=0;i<p;i++)
{
for(j=0;j<c;j++)
{
if(arr[i][j]) free(arr[i][j]);
}
if(arr[i]) free(arr[i]);
}
if(arr) free(arr);
}
Usage could be:
free3D(array,3,3);
I'm trying to get monochrome image from .bmp image with using bitmap_image.hpp library. But in one place (Pic[i][j] = 0.3 * r + 0.59 * g + 0.11 * b;) i receive that error: Unhandled exception at 0x0019BD8F in PicCircle.exe: 0xC0000005: Access violation writing location 0x011CF000. . So, that's wrong with it?
code:
#define _SCL_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "bitmap_image.hpp"
#define C 0.01
double** ArrayCreate ( int M, int N )
{
int i;
double** ArrayRoot;
ArrayRoot = (double **)malloc(sizeof(double*) * M);
for (i = 0; i < M; i++)
ArrayRoot[i] = (double *)malloc(sizeof(double) * N);
return ArrayRoot;
}
void ArrayDestroy ( double** Array , int M)
{
int i;
for (i = 0; i < M; i++){
Array[i] = (double *)realloc(Array[i], 0);
};
Array = (double **)realloc(Array, 0);
}
void main ( void )
{
double** Pic;
unsigned char r, g, b;
int H, W, i, j;
bitmap_image image("m1.bmp");
H = image.height();
W = image.width();
Pic = ArrayCreate(H, W);
for (i = 0; i < W; i++)
for (j = 0; j < H; j++)
{
image.get_pixel(i, j, r, g, b);
Pic[i][j] = 0.3 * r + 0.59 * g + 0.11 * b;
}
for (i = 0; i < W; i++)
for (j = 0; j < H; j++)
{
if (abs(sqrt(pow(Pic[i + 1][j] - Pic[i][j], 2) + pow(Pic[i][j + 1] - Pic[i][j], 2))) >= C)
Pic[i][j] = 1;
else
Pic[i][j] = 0;
}
ArrayDestroy(Pic, H);
}
In your first loop you access the Pic array as Pic[width][height], but in the second loop you access it as Pic[height][width].
One of those two is incorrect, probably the first one.
Fixing your for loop should correct the issue.
This:
ArrayRoot = (double **)malloc(sizeof(int*) * M);
looks super-broken; it assumes sizeof (int *) to be the same as (sizeof double *) which is probably true, but still a very broken thing to write.
The follow-up is worse:
ArrayRoot[i] = (double *)malloc(sizeof(int) * N);
since sizeof (int) is very probably smaller than sizeof (double) this is going to lead to horror.
The way to avoid this category of error is to never write the type name in the malloc() argument: dereference the pointer being assigned to, instead. The latter would then become:
ArrayRoot[i] = malloc(N * sizeof *ArrayRoot[i]);
^^^^^^^^^^^^^
this part is to
the left of the =
This also drops the cast of course.
I have to assign memory to a 3D array using a triple pointer.
#include <stdio.h>
int main()
{
int m=10,n=20,p=30;
char ***z;
z = (char***) malloc(sizeof(char**)*m*n*p);
return 0;
}
Is this correct way of doing this?(I think what i am doing is incorrect.)
To completely allocate a 3D dynamic array you need to do something like the following:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int m=10,n=20,p=30;
char ***z;
z = malloc(m * sizeof(char **));
assert(z != NULL);
for (i = 0; i < m; ++i)
{
z[i] = malloc(n * sizeof(char *));
assert(z[i] != NULL);
for (j = 0; j < n; ++j)
{
z[i][j] = malloc(p);
assert(z[i][j] != NULL);
}
}
return 0;
}
Freeing the data is left as an exercise for the reader.
There's no need to cast the return value of malloc(), in C.
And if you expect to store m * n * p characters directly (and compute the address yourself), then you should of course not scale the allocation by the size of a char **.
You mean:
int m = 10, n = 20, p = 30;
char *z = malloc(m * n * p * sizeof *z);
This will allocate 10 * 20 * 30 = 6000 bytes. This can be viewed as forming a cube of height p, with each "slice" along the vertical axis being n * m bytes.
Since this is for manual addressing, you cannot use e.g. z[k][j][i] to index, instead you must use z[k * n * m + j * m + i].
If you don't need the memory to be allocated in a single, contiguous chunk (which IME is the usual case), you would do something like this:
char ***z;
z = malloc(sizeof *z * m); // allocate m elements of char **
if (z)
{
int i;
for (i = 0; i < m; i++)
{
z[i] = malloc(sizeof *z[i] * n); // for each z[i],
if (z[i]) // allocate n elements char *
{
int j;
for (j = 0; j < n;j++)
{
z[i][j] = malloc(sizeof *z[i][j] * p); // for each z[i][j],
if (z[i][j]) // allocate p elements of char
{
// initialize each of z[i][j][k]
}
}
}
}
}
Note that you will need to free this memory in reverse order:
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
free(z[i][j];
free(z[i]);
}
free(z);
If you really need the memory to be allocated in a contiguous chunk, you have a couple of choices. You could allocate a single block and compute your offsets manually:
char *z = malloc(sizeof *z * m * n * p); // note type of z!
...
z[i * m + j * n + k] = some_value();
When you're done, you just need to do a single free:
free(z);
If you have a C99 compiler or a C11 compiler that supports variable-length arrays, you could do something like this:
int m=..., n=..., p=...;
char (*z)[n][p] = malloc(sizeof *z * m);
This declares z as a pointer to an nxp array of char, and we allocate m such elements. The memory is allocated contiguously and you can use normal 3-d array indexing syntax (z[i][j][k]). Like the above method, you only need a single free call:
free(z);
If you don't have a C99 compiler or a C11 compiler that supports VLAs, you would need to make n, and p compile-time constants, such as
#define n 20
#define p 30
otherwise that last method won't work.
Edit
m doesn't need to be a compile-time constant in this case, just n and p.
You would need the following nested loop -
z = (char**)malloc(sizeof(char*) * m);
for (int i = 0; i < m; ++i)
{
*(z + i) = (char*)malloc(sizeof(char*) * n);
for (int j = 0; j < n; ++j)
{
*(*(z + i)) = (char)malloc(p);
}
}
May not be synactically accurate, but it should be something along these lines.
You want sizeof(char) not sizeof(char**) as the latter will give you the size of a pointer which on most modern systems will be 4 bytes instead of the 1 you're expecting.