How to store floats in array to be used later? - c

how can a user of a program store info in arrays such as a float number and can be calculated for an average later in the program? im trying to make a program to calculate someones grade point average.

int maxGrades = 50; // pick this
int numGrades = 0;
float[] grades = malloc (sizeof (float) * maxGrades);
// in a loop somewhere
if(numGrades == maxGrades) {
maxGrades *= 2;
float[] newGrades = malloc (sizeof (float) * maxGrades);
for(int i = 0; i < numGrades; i++) newGrades[i] = grades[i];
grades = newGrades;
}
grades[numGrades++] = theNewestGrade;

Transitting from java to C, the biggest "concept jump" you have to make is Pointers.
Try allocating your floats this way:
float *float_array = malloc(amount_of_elemts_in_array * sizeof(float))
You can then iterate through using
float_array[index]
Having this pointer will enable you to pass float_array in and out of functions by reference which is a great convenience since you don't want to recreate instances over every function call.
Pass float_array into functions using:
Function Declaration: void function_that_uses_float_array(float *placeholder);
Function Call: function_that_uses_float_array(placeholder);
Pass float_array out of functions using:
Return statement: return a_float_pointer;
One level up the stack: float_array = function_that_returns_a_float_pointer();
Arrays are automatically passed by reference.
Hope this helps point you in the right direction.

Related

Passing one dimension of a 2D dynamic array to a function

I have a 2D array that I'm dynamically allocating at runtime, like so
accData = calloc(nbox, sizeof(double *));
for(bb = 0; bb < nbox; bb++)
accData[bb] = calloc(usedTime * usedChan, sizeof(double *));
and I want to only pass the second dimension to my function. This array represents data defined in several different "boxes", and for each box, I want to pass the relevant information to the function, process it and store it in the same array. Currently this is how I'm doing it -
for(bb = 0; bb < nbox; bb++)
fftAndsubtract(accData[bb], ntime, nchan, nsigma, bb);
where fftAndSubtract performs an FFT (fast fourier transform) and a few other operations. The function definition is like so:
int fftAndsubtract(double accData[], ntime, nchan, nsigma, bb);
but accData doesn't seem to hold the modified values that fftAndSubtract produces. I've verified this, because I'm printing the outputs of the operations done in the function itself. The compiler isn't complaining, so I didn't think this was wrong. Is there a better way to do this?
Question: Is there a way I can pass accData[bb] to the function so that the output of the operations done by the function are stored in the same array?
I'm guessing that you're on a 32-bit machine. Then pointers are 32-bits, while double are 64 bits.
This means that your allocation of the "second dimension" in the loop is wrong, and only allocates half of the data that is needed. To solve this, change to sizeof(double) in the calloc call in the loop.
Technically you might want to change the type of the accData argument in fftAndsubtract to a pointer instead, as that's what your passing it.
I like the way you're doing it, when I first read the question I was thinking you'd have to do some fancy indexing to hop from value to value... but I looked closer and I like the array of array idea. This is how I would implement it:
double *accData = calloc(nbox, sizeof(double *)); // Alloc array of double* pointers
for(bb = 0; bb < nbox; bb++)
accData[bb] = calloc(usedTime * usedChan, sizeof(double)); // Alloc array of doubles
for(bb = 0; bb < nbox; bb++)
fftAndsubtract(accData[bb], ntime, nchan, nsigma, bb);
// Remember accData is an array of an array of doubles
// accData[bb] is an array of doubles
...
int fftAndSubtract(double* accData, int nTime, int nchan, int nsigma, int bb) {
... do fancy fft stuff ...
for(int i=0; i < nTime * nchan; i++) { // loop through entire array
double result = ... do stuff with accData[i] ...
accData[i] = result;
}
return someReturnValue;
}
This is how I think about how your accData is laid out in memory (this is bad though because the first row is contiguous data and the columns (after the first row) are also contiguous data, but the columns have no correlation to each other):
double* accData[0] accData[1] accData[2] accData[3] accData[4]
double accData[0][0] accData[1][0] accData[2][0] accData[3][0] accData[4][0]
double accData[0][1] accData[1][1] accData[2][1] accData[3][1] accData[4][1]
double accData[0][2] accData[1][2] accData[2][2] accData[3][2] accData[4][2]
double accData[0][3] accData[1][3] accData[2][3] accData[3][3] accData[4][3]
double accData[0][4] accData[1][4] accData[2][4] accData[3][4] accData[4][4]

Adding double type arrays to a structure of undefined length arrays

Say that I have the following arrays that I call in a function:
int n = 20;
double x[] = {
0.003435700407453, 0.018014036361043, 0.043882785874337, 0.080441514088891,
0.126834046769925, 0.181973159636742, 0.244566499024586, 0.313146955642290,
0.386107074429177, 0.461736739433251, 0.538263260566749, 0.613892925570823,
0.686853044357710, 0.755433500975414, 0.818026840363258, 0.873165953230075,
0.919558485911109, 0.956117214125663, 0.981985963638957, 0.996564299592547
};
double w[] = {
0.008807003569576, 0.020300714900193, 0.031336024167055, 0.041638370788352,
0.050965059908620, 0.059097265980759, 0.065844319224588, 0.071048054659191,
0.074586493236302, 0.076376693565363, 0.076376693565363, 0.074586493236302,
0.071048054659191, 0.065844319224588, 0.059097265980759, 0.050965059908620,
0.041638370788352, 0.031336024167055, 0.020300714900193, 0.008807003569576
};
I would like to return the int n and the two arrays. I can do this by using a structure which is easy if I know the length of array x and w. However, the function depending on the inputs can return an array x of length 2,4,6,15, etc and an array w of length 2,4,6,15, etc. I do not know the length of array w and x.
I've created a structure:
struct quadpts{ //structure used to pass multiple values into roeFlux
int n; //The specific heat ratio
double *x;
double *w;
};
typedef struct quadpts Quadpts;
and used:
Quadpts qpt = (Quadpts) malloc(size(Quadpts));
to assign the varied length values in array x and w. However, I realized that people were adding one value at a time in many of the examples I have seen and looked up. Is it possible to assign a whole array to a varied length array in a structure? Or am I limited to filling the array in the structure 1 by one. Can this be done using a for loop? If so, would I have to define
Quadpts qpt = (Quadpts) malloc(size(Quadpts));
in a different way each time to account for the new addition to the structure array?
Thank you for your help. I'm new at C and am limited to MATLAB knowledge.
EDIT:
I realized that I have problems with those big arrays. I'm using a switch case syntax in order to allocate different size arrays to the variable x and w. But I realized that I need to designate the size of those arrays to begin with and they will only be seen within the for loop. How can I make it such that the arrays are seen outside of for loops such that I can save them to the structures? The following is a shorten version of my code. I'm constantly getting error at double x[n] as previous definition was here or redefinition.
double quad1d(int pqOrder){
int n;
switch(pqOrder)
{
case 1:
n = 1;
double x[n] = {
0.500000000000000
};
double w[n] = {
1.000000000000000};
break;
case 3:
// Order 3 Gauss-Legendre points
n = 2;
double x[n] = {
0.211324865405187, 0.788675134594813
};
double w[n] = {
0.500000000000000, 0.500000000000000
};
break;
}
int i;
Quadpts * qpt = (Quadpts*)malloc(sizeof(Quadpts));
for (i=0; i<n; i++){
qpt->x = malloc(qpt->x_len * sizeof(double));
qpt->w = malloc(qpt->w_len * sizeof(double));
qpt.x=x[i];
qpt.w=w[i];
}
return &(qpt[0]);
}
There may be other problems but one thing that stood out immediately was that having pointers in a struct isn't good enough, you have to use malloc() for each one in your case.
And if you declare those big arrays inside your function they will be on the stack which will be eventually overwritten.
Use:
struct quadpts{ //structure used to pass multiple values into roeFlux
int n; //The specific heat ratio
double *x;
int x_len;
double *w;
int w_len;
};
And inside the function:
qpt->x = malloc(qpt->x_len * sizeof(double));
qpt->w = malloc(qpt->w_len * sizeof(double));
And then fill your arrays.
Don't forget to free() them once you are done using them [outside your function].
Another mistake is that you should use malloc() with a struct pointer:
Quadpts * qpt = (Quadpts*)malloc(sizeof(Quadpts));
You would also need 3 lines of code once you no longer need it to avoid memory leaks.
free(qpt->x);
free(qpt->w);
free(qpt);

C: I need a function which will accept and return a variably sized array

If this is a beginner's question, my apologies - most of my programming has been in very high level langauges, and I have limited expertise in C. (This is the sort of thing I could do very easily in languages such as Matlab, Octave, Sage, Maxima etc, but for this I need the speed of C).
But anyway... I have an array whose size is set at run time with malloc:
int *A = malloc(m * sizeof(int));
where m is computed from some values provided by the user. I have a function "update" which updates the array (or, if you prefer, takes the array as input and returns another as output). This update function may be called upwards of 10^8 times.
So the function itself can't introduce the appropriately sized output array with malloc, or the memory will be used up. So, for example, I can't do this:
int * update(int *L) /* produces next iteration of L */
{
int *out = malloc(m * sizeof(int));
/* do some stuff with L and produce new array out */
return (out);
}
I've tried to make out a static variable outside the update function:
static int *out;
and define its size in main:
out = malloc(m * sizeof(int));
But this doesn't seem to work either.
Anyway, I would be very grateful of some advice - I think I've exhausted the excellence of google.
Allocate the array outside of update, then pass a pointer to it:
void update(int const *L, int *out)
{
// whatever
}
Call as
int *A = malloc(m * sizeof(int));
if (A == NULL)
// handle error
for (i=0; i < N_ITER; i++)
update(L, A);
Though you may want to redesign the program so that it updates L in-place.
So if you are simply wanting to work on the data that is coming into the function directly, then what you have is partially already correct. The only thing that I would do is to add the size of the array as an input parameter to the routine to look like this:
void update(int * L, unsigned int size){
unsigned int count;
// Make sure the array has actually been allocated from outside
if(L == NULL) return;
// Example work on L just as if it is an array of values
for(count = 0; count < size; count++){
L[count] = L[count] + 1;
}
}
REMEMBER, this will work if you DO NOT wish to maintain the original data within L. If you do wish to maintain the original data, then larsmans answer will work better for you.
Also remember that you will have to malloc whatever variable you wish to input into L, outside and prior to your update routine, and free at some other point.
int * myVar = (int *)malloc(m * sizeof(int));
update(myVar, m);
// Other work to be done
free(myVar);
You should use realloc.
int *a = realloc(a, m * sizeof(a[0]));
It will work just as malloc in the first run but then it will reallocate a different sized array. You should note that the new array might or might not have the previous values assigned in it. You should assume that it has garbage like all things given by malloc.
Here is a good explanation of using realloc.
http://www.java-samples.com/showtutorial.php?tutorialid=589
NOTE : sizeof(a[0]) is equal to sizeof int but if you change int it will still be right

realloc can not access to the new size from other function

Im trying to increase the size of a **array with realloc which I have created with malloc.
I committed the **array to a function where I would like to increase the size.
Here is the part which increase the size:
imginf->height = imginf->height * 2;
imginf->width = imginf->width * 2;
array = realloc(array, imginf->height * sizeof(d*));
for(int i = 0; i < imginf->height; i++) {
array[i] = malloc(imginf->width * sizeof(d));
}
After that, I fill the array with two for loops. Everything works fine!
In the next function I try to save that array in a file. Here I use also two for loops.
With the first for loop I walk through the height and here I get the problem.
If the loop counter is (imginf->height /2) I ran out of the array. For the width everything’s works fine.
What went wrong? Especially, why could I fill the array?
Edit
Here the function definition for saving:
void Save(char * newname, inf imginf, d **array);
d is a struct with 3 unsigned chars.
Here the definition for the realloc function:
void reallocBig(inf *imginf, d **array);
Greetz.
C is a pass-by-value language. Your reallocBig function can't modify the value of the array in the caller. You need to change it to take a d *** parameter, and "fill in" that pointer in the function:
void reallocBig(inf *imginf, d ***array)
{
...
*array = realloc(...)
for (...)
(*array)[i] = ...
...
}
The C FAQ has a question about precisely your problem. You should also note that your current implementation leaks all of the previous entries in the array.

Why does my 2D array cause a bus error in C?

I'm attempting to create a simple 2D array in C but apparently running into some memory trouble. My setup is simple enough and I can't tell what's wrong. I admit that my understanding of pointers is insufficient, but I still think this should be working. Can anyone see the flaw here?
typedef unsigned int DATUM;
DATUM **series_of_data;
void initialize_data()
{
*series_of_data = (DATUM *) malloc(1024 * sizeof(DATUM));
}
This causes my program to crash with a bus error when I run it.
series_of_data is actually not allocated.
You have various way to allocates a 2D array, either using the array of rows model whcih has bad cache coherency and thus has usually bad performances or to use the Iliffe vector adviced in Numerical recipes in C that consists in allocating one huge h*w memory block and a side pointer array which contains the beginning of your rows (or columns) :
DATUM** alloc_array( int h, int w )
{
int i;
DATUM** m = (DATUM**)malloc(h*sizeof(DATUM*));
m[0] = (DATUM*)malloc(h*w*sizeof(DATUM));
for(i=1;i<h;i++) m[i] = m[i-1]+w;
return m;
}
void release_array(DATUM** m)
{
free( m[0] );
free( m);
}
int main()
{
int r,c;
DATUM** tab;
int width = 5;
int height = 3;
tab = alloc_array(height, width); /* column first */
for(r = 0;r<height;++r)
for(c = 0;c<width;++c)
tab[r][c] = (1+r+c);
for(r = 0;r<height;++r)
{
for(c = 0;c<width;++c)
{
printf("%d\t",tab[r][c]);
}
puts("");
}
release_array(tab);
}
Data are nicely packed in memory, so cache are happy and you keep the [][] access pattern.
As a matter of speed this is in +/-3% speed of the classical DATUM* + polynomial access method.
series_of_data is an invalid pointer - you don't assign it to anything. When you try to assign to its memory location (*series_of_data = ...), it's putting stuff in a random place, which is likely to not do what you want. You have to point series_of_data somewhere useful, e.g.
series_of_data = (DATUM **)malloc(16 * sizeof(DATUM *))
for an array with 16 slots for DATUM * pointers in it.
You haven't allocated the series_of_data pointer before you assign to *series_of_data.
For example, if series_of_data is intended to be an array then you would need to write something like this:
series_of_data = malloc(n*sizeof(DATUM*));
where n is the length of the series_of_data array.
Only after you have done this can you assign to *series_of_data.

Resources