Initialization of an array of pointers to pointers - arrays

I need to initialize an array of pointers to pointers to four variables a, b, c and d in this way:
float a = 2.8f, b = 3.7f, c = 4.6f, d = 5.5f;
float *pts[] = { &a, &b, &c, &d };
float **ptpts[4];
void main() {
ptpts[0] = &pts[0];
ptpts[1] = &pts[1];
ptpts[2] = &pts[2];
ptpts[3] = &pts[3];
int i;
for (i = 0; i < 4; i++) {
printf("ptpts[%d] = %f\n", i, **ptpts[i]);
}
}
Isn't there a simpler way to initialize the array ptpts directly at declaration using directly the array pts in order to get rid of the assignment of each element in ptpts one by one. Something like that (but doesn't work):
float *pts[] = { &a, &b, &c, &d };
float **ptpts = &pts; // => initialization from incompatible pointer type
In other words, isn't there a way to get the corresponding array of references from an array of pointers ?
Edit:
Following some comments, I give here a piece of background to explain how I came to that question. This may help to propose the solution or give idea for a better architecture.
I have the following interface (interface.h) for the program I'm developing. Depending on a flag PTTYPE defined at compilation time, the interface will be a set of variables or a set of pointers depending on the environment where the program is deployed. The program must be compliant with both kind of interface type (PTTYPE=1 or PTTYPE=0).
// interface.h
#if PTTYPE
float *pta, *ptb, *ptc, *ptd;
#define a (*pta)
#define b (*ptb)
#define c (*ptc)
#define d (*ptd)
#else
float a, b, c, d;
#endif
I'm not the owner of this interface file and can't modify it. I must just include this file in my program and want to have a simple and unique way to reach the values. That's why I thought about using an array of pointers to pointers and would have something like that:
#include "interface.h"
#if PTTYPE
float **ptpts[]={ &pta, &ptb, &ptc, &ptd };
#else
float *pts[]={ &a, &b, &c, &d };
float **ptpts = &pts; // => initialization from incompatible pointer
#end
void main() {
a=2.8f;
b=3.7f;
c=4.6f;
d=5.5f;
int i;
for (i = 0; i < 4; i++) {
printf("ptpts[%d] = %f\n", i, **ptpts[i]);
}
}

float ..... = &pts;
Yes you can but you need another pointer type (pointer to array):
float a = 2.8f, b = 3.7f, c = 4.6f, d = 5.5f;
float *pts[] = { &a, &b, &c, &d };
float *(*ptpts)[4] = &pts;
for (size_t i = 0; i < 4; i++)
{
printf("*ptpts[0][%zu] = %f\n", i, *ptpts[0][i]);
}
or
for (size_t i = 0; i < 4; i++) {
printf("ptpts[%zu] = %f\n", i, *(*ptpts[i]));
}
Yes you can even without any variables
int main(void)
{
float **pptrs[] = {(float **){&(float *){&(float){1.0f}}},
(float **){&(float *){&(float){2.0f}}},
(float **){&(float *){&(float){3.0f}}},
(float **){&(float *){&(float){4.0f}}}, };
}

The array can be defined and initialized inline this way:
float **ptpts[] = { &pts[0], &pts[1], &pts[2], &pts[3]};
If the array is global and the initization local in main, a loop or a series of assignments is required.

It's okay to use whitespace to aid readability.
int main() {
float a=2.8f, b=3.7f, c=4.6f, d=5.5f;
float *pts[]={ &a, &b, &c, &d };
// What you want?
float **ptpts[] = { &pts[0], &pts[1], &pts[2], &pts[3] };
for( int i = 0; i < 4; i++ )
printf("ptpts[%d] = %f\n", i, **ptpts[i]);
return 0;
}
Output:
ptpts[0] = 2.800000
ptpts[1] = 3.700000
ptpts[2] = 4.600000
ptpts[3] = 5.500000

So, thanks to the help of 0___________, I was able to find a solution which answers to my initial problem (i.e. initialize the array of pointers to pointer with either pointers or variable). In this way, I'm not using any more the intermediate array of pointer pts but create directly the array of pointers to pointer using the compound-literals .
Here is the initialization part of the array ptpts:
#if ITYPE
#define ADAPT(name) pt##name
#else
#define ADAPT(name) (float *){&name}
#endif
float **ptpts[] = { &ADAPT(a),
&ADAPT(b),
&ADAPT(c),
&ADAPT(d) };

Related

Simple memory allocation for embedded application

I need to have dynamic memory allocation without the use of malloc in an embedded application.
As we have enough RAM, I would like to allocate a big array (A[A_MAX]) on startup and have buffer arrays (B[]) within this one big array.
They would always begin at A[0] and be as long as they need (at max A_MAX, but mostly shorter).
Example:
at start up:
A[8] = {0,0,0,0,0,0,0,0};
declaring B[4] at A[0] and filling B with ones
B[4] = {1,1,1,1};
now A should look like this:
A[8] = {1,1,1,1,0,0,0,0}
How can I do this?
I looked at the sourcecode for malloc() and it does return the address of the next free part of the heap.
but when I use
float *B[4] = &A[0];
my compiler returns an error (invalid initializer)
As #neon mentioned I wanted to write an address to a float array.
Writing it like float *B = A[0] worked like a charm.
You may do:
#include <stdalign.h>
#define A_MAX 8
alignas(max_align_t) char _memory[A_MAX] = {0};
then you can just use pointers:
int main() {
{
float *floatdata = (void*)_memory;
// use floatdata
}
{
int *intdata = (void*)_memory;
// use intdata
}
}
I would write a handy function to calculate the maximum size for error checking:
// query the max size and allocate
inline void *dataalloc(size_t elemsize, size_t *n) {
*n = sizeof(_data) / elemsize;
return _data;
}
and do:
size_t size;
float *floatdata = dataalloc(sizeof(*floatdata), &size);
// use as-if floatdata[size]
for (size_t i = 0; i < size; ++i) floatdata[i] = i;
do you mean something like ? I'm using pointers to the array
#include <stdio.h>
#include <stdlib.h>
void allocator(float* src,int SrcSize,float **dst,int size,int pos){
if(size <= SrcSize)
for(int i=0;i<size;i++){
dst[i] = &(src+pos)[i];
}
}
int main()
{
float A[8] = {0,0,0,0,0,0,0,0};
float *B[4];
float *C[4];
allocator(A,sizeof(A)/sizeof(float),B,4,0);
*B[2] = 4;
allocator(A,sizeof(A)/sizeof(float),C,4,4);
*C[0] = 6;
printf("A[2] value is : %f\n" , A[2]); // output is 4.000
printf("A[4] value is : %f\n" , A[4]); // output is 6.000
return 0;
}

Cast void pointer to double without knowing its type in C

I need to write a function which takes as parameters a void pointer (representing an array) and an integer which represents the length of the array. In the function, I need to cast this void pointer into a double one. The problem is that the void pointer can represent an array of integers or floats or doubles.
So the following is obviously not working in case the void pointer represents an array of integers or floats:
void foo(void *v,int n){
double *values;
values=(double*)v;
for(i=0;i<n;i++)
printf("%f\n",values[i]);
}
so this will print the correct output:
foo((double[]){1,2,3,4},4);
and this will print a wrong output:
foo((int[]){1,2,3,4},4);
foo((float[]){1,2,3,4},4);
So... can I correctly cast the void pointer to a double one only knowing that it can be an array of integers or floats or doubles? And is it necessary to have the length of the array or I can calculate it somehow?
P.s. without using callbacks
can I correctly cast the void pointer to a double one only knowing that it can be an array of integers or floats or doubles?
No, you cannot. You need to pass the type information somehow.
And is it necessary to have the length of the array or I can calculate it somehow?
It's necessary to pass the length.
You can "hide" the information inside a struct
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
enum etype { INTEGER, FLOAT, DOUBLE };
struct data {
void *values;
size_t n;
enum etype type;
};
void foo(struct data *x) {
int *xd = x->values;
float *xf = x->values;
double *xg = x->values;
for (int k = 0; k < x->n; k++) {
switch (x->type) {
default: printf("%g ", xg[k]); break;
case FLOAT: printf("%f ", xf[k]); break;
case INTEGER: printf("%d ", xd[k]); break;
}
}
puts("");
}
int main(void) {
struct data x;
x.values = malloc(4 * sizeof(int));
((int*)(x.values))[0] = 42;
((int*)(x.values))[1] = -1;
((int*)(x.values))[2] = 0;
((int*)(x.values))[3] = 999;
x.n = 4;
x.type = INTEGER;
foo(&x);
x.values = calloc(4, sizeof(float));
x.type = FLOAT;
float tmp = 3.14159;
memcpy(((float*)(x.values))+1, &tmp, sizeof (float));
foo(&x);
free(x.values);
x.values = calloc(4, sizeof(double));
x.type = DOUBLE;
((double*)(x.values))[2] = 2.7182818;
foo(&x);
free(x.values);
}
See code running on ideone

How to swap 2 numeric numbers of unknown exact type, via two void pointer parameters?

I need to write a function that replaces 2 "numeric numbers", of otherwise unknown type.
I don't know the exact type and I can only use 2 parameters.
So this is what I have tried:
void swap(void *p1, void *p2)
{
char p;
char * q1 = (char *)p1;
char * q2 = (char *)p2;
for (int i = 0; i < sizeof(long double); i++)
{
p = q1[i];
q1[i] = q2[i];
q2[i] = p;
}
}
Usage:
double a = 100123000000.2;
double b = 100065450000.3;
printf("a: %1f, b: %1f\n", a, b);
swap(&a, &b)
printf("a: %1f, b: %1f\n", a, b);
This works fine but my question is what if my number is bigger then long double (or there is no one..)
Is my solution OK?
This works fine but my question is what if my number is bigger (?)
Is my solution is OK ?
Code will have trouble unless it knows the exact size. So, no, OP's solution is not OK.
Somehow void swap() needs to know the size of the data to swap.
i can only use 2 parameters.
Code can cheat and put all the data into 1 argument as a compound literal, since C99.
typedef struct {
void *a;
void *b;
size_t sz;
} swap_T;
// Only 1 parameter!!
void swap(swap_T sw) {
unsigned char * q1 = sw.a;
unsigned char * q2 = sw.b;
while (sw.sz > 0) {
sw.sz--;
unsigned char p = q1[sw.sz];
q1[sw.sz] = q2[sw.sz];
q2[sw.sz] = p;
}
}
int main(void) {
double a = 100123000000.2;
double b = 100065450000.3;
printf("a: %g, b: %g\n", a, b);
swap(((swap_T ) { &a, &b, sizeof a } )); // Compound literal
printf("a: %g, b: %g\n", a, b);
return 0;
}
Output
a: 1.00123e+11, b: 1.00065e+11
a: 1.00065e+11, b: 1.00123e+11
Code could wrap the swap(((swap_T ) { &a, &b, sizeof a } )) in a macro that looks like a function call of 2
#define SWAP(a,b) (swap(((swap_T ) { &(a), &(b), sizeof (a) } )))
...
SWAP(a,b);
As long as a is not an expression with a variable logic array (VLA) and with side-effects, the macro should work fine.
Of course, best if a,b are the same type.
Your program should try to retrieve sizeof of its argument to know how many bytes to swap - perhaps as a third argument - you have no way of telling otherwise how big an argument is. With current function you will overwrite memory which will end up badly - especially in a bigger program. For example, consider a following program.
#include <stdio.h>
int main() {
int a[] = {1, 2, 3, 4, 5, 6, 7, 8};
swap(&a[0], &a[4]);
for (int i = 0; i < 8; i++) {
printf("%d\n", a[i]);
}
}
Which will return 5, 6, 7, 8, 1, 2, 3, 4 - which clearly isn't expected - only 0th and 4th array elements should have been swapped.
It's possible to hide getting size behind a macro if needed.
#define SWAP(a, b) swap(&(a), &(b), sizeof(a))

returning two variables that have multiple values

I am trying to use a function that will calculate values for h and then input these values of h into an equation that will calculate n. This is what my code currently looks like...
int findN(double xI, double xF) {
double h = 0.1;
int n;
do {
printf_s("%8.5f \n", h);
n = ((xF - xI) / h);
h = h / 10;
printf_s("%6d \n", n);
} while (h >= 0.00001);
return n;
}
I know that this function will only return n currently, but as i am new to this i am unsure as to how to also return all the values of h as well as all the values of n... If someone could assist me and show me how to return all the values for n & h, it would be much appreciated.
Thanks.
Typical approach to return multpile values is using arrays and pass its pointer to function:
int f(double *h) {
h[0] = 1.1;
h[1] = 2.2;
}
int main()
{
// create pointer
double *h;
// initialize it with memory block
h = malloc(2*sizeof(double));
// call the function
f(h);
// show output
printf_s("%8.5f \n", h[0]);
printf_s("%8.5f \n", h[1]);
// release memory block
free(h);
return 0;
}
Also same array may be created without memory allocation. It is more simple but arrays exists only until execution is not leave away from function scope where it declared.
int main()
{
// create array
double h[2];
// call the function
f(h);
// show output
printf_s("%8.5f \n", h[0]);
printf_s("%8.5f \n", h[1]);
return 0;
}
And if you can know count of element only during function call you can allocate array in function and return array by pointer and release array at caller.
double* f() {
// create pointer
double *h;
// some size calculations
int size = 1+1;
// initialize it with memory block
h = malloc(size*sizeof(double));
// fill the array
h[0] = 1.1;
h[1] = 2.2;
// return array by pointer
return h;
}
int main()
{
// create pointer
double *h;
// call the function
h = f();
// show output
printf_s("%8.5f \n", h[0]);
printf_s("%8.5f \n", h[1]);
// release memory block
free(h);
return 0;
}
There are many ways to solve this. Another is to return a struct.
Below, findN() returns one object. It just happens that the object contains two members. This approach is suitable when with small objects. With large objects,other approaches should be considered.
typedef struct {
int n;
double h;
} nh;
nh findN(double xI, double xF) {
nh retval;
retval.h = 0.1;
do {
printf_s("%8.5f\n", retval.h);
retval.n = ((xF - xI) / retval.h);
retval.h = retval.h / 10;
printf_s("%6d\n", retval.n);
} while (retval.h >= 0.00001);
return retval;
}
// usage exanple
nh y;
y = findN(1.23, 4.56);
printf_s("h:%8.5f, n:%6d\n", y.h, y.n);
Read into pointers if you want to learn more. But essentially by sending h as a pointer it will return it's value to main.
#include <stdio.h>
int findN(double xI, double xF, double h[]) {
int i = 0;
int n;
h[i] = 0.1;
do {
i++;
printf_s("%8.5f \n", *h);
n = ((xF - xI) / (*h));
h[i] = h[i-1] / 10;
printf_s("%6d \n", n);
} while (h[i] >= 0.00001);
return n;
}
int main()
{
double h[100];
double xI = 1.0, xF = 1.0;
int n;
n = findN(xI, xF, h);
return 0;
}
Read pointers,you will be able to return as many values you want to return,when calling function through main add &h in actual parameters,it means findN(xI,xF,&h) and in declaring the function findN add double *h in formal parameters,that is int findN(double xI,double xF,double *h)...."meaning of * is -value at address of....meaning of & is address of.This will make changes in h globally in this program as the vale is changing in its address.You can return even more values like this using more variables.This is called returning values indirectly.Vote for my answer if its applicable.
The simplest way to handle this is change the function to accept pointers to variables that will accept the values of n and h. Then the function will dereference those pointers to update the relevant variables in the calling function.
void findN(double xI, double xF, int *ret_n, double *ret_h)
{
...
*ret_n = n;
*ret_h = h;
}
Then you can call your function like this:
int n;
double h;
findN(1.2, 3.4, &n, &h);
This method is fine for a relatively small number of parameters. If the number of parameters gets to be too large, you can instead create a struct containing all of the values to be returned either pass in the address of the struct or just return the struct outright.

C malloc of pointer to pointer inside function not giving correct size

So I am now rewriting my fortran code in C (to use CUDA), and apparently I do not understand how to properly use malloc and pointers. I am trying to make the main function just calls to other functions, which need to malloc arrays that will then be used inside other functions. So, I am passing pointers of pointers to them as per this post: C Programming: malloc() inside another function
But the right amount of memory is not being allocated so I get segmentation faults. Here is the code:
#include <stdio.h>
#include <stdlib.h>
//#include <cuda.h>
#include <math.h>
//#include "cublas.h"
//datatype to match FORTRAN complex type
typedef float real;
typedef struct{
int nx;
int ny;
int nz;
int sz;
int tz;
} states;
void set_SPB(real **,int,states **,states **,int **);
//void set_SPB();
int find_minimum(int a[], int n,int start);
const real hc =197.32697,pi=3.1415927;
int main(){
int nmax = 2, A = 28;
real *etemp, *fock;
int *Ndex,*lookup,*lookup_a;
states *channel,*SPB;
//!generates the single particle basis to be used
set_SPB(&etemp,nmax,&SPB,&channel,&Ndex);
free(etemp);
free(Ndex);
free(SPB);
return 0;
}
void set_SPB(real **etemp,int nmax,states **SPB,states **channel,int **Ndex){
int tot_orbs = (2*nmax+1)*(2*nmax+1)*(2*nmax+1)*4;
int D = tot_orbs/4;
int Nalpha = (2*nmax+1)*(2*nmax+1)*(2*nmax+1)*9;
real E;
*etemp = (real*)malloc(D);
*Ndex = (int*)malloc(D*3);
*SPB = (states*)malloc(tot_orbs);
printf("orbits without spin degeneracy %d \n",D);
printf("size of etemp %ld \n",sizeof(*etemp)/sizeof(*etemp[0]));
return;
int i = 0;
for(int nx =-nmax;nx<=nmax;nx++){
for(int ny =-nmax;ny<=nmax;ny++){
for(int nz =-nmax;nz<=nmax;nz++){
E = 0.5*4.0*pi*pi*(nx*nx+ny*ny+nz*nz);
//printf("%d\n",i);
*etemp[i] = E;
*Ndex[0*D+i] =nx;
*Ndex[1*D+i] = ny;
*Ndex[2*D+i] = nz;
i+=1;
}
}
}
return;
}
Also I am not sure exactly if my assignments of the arrays are correct.
Specifically the print to find the number of elements of that have been allocated always gives 2, when it should be D = 125.
I cannot believe that float and int take only 1 byte in your environment.
Multiply the size to be allocated by size of their elements.
*etemp = malloc(sizeof(**etemp) * D);
*Ndex = malloc(sizeof(**Ndex) * D*3);
*SPB = malloc(sizeof(**SPB) * tot_orbs); /* not sure because this is not used */
Note that they say you shouldn't cast the result of malloc() in C.
Also note that [] operator has higher precedence than * operator, so you have to use parentheses to use the arrays.
(*etemp)[i] = E;
(*Ndex)[0*D+i] =nx;
(*Ndex)[1*D+i] = ny;
(*Ndex)[2*D+i] = nz;

Resources