The purpose of "new double" - arrays

public class JAVA_Guevarra {
public static void main(String[] args) {
//These are the variables
double empBasicPay[] = {4000,5000,12000,6000,7500};
double empHousingAllow[] = new double[5];
int i;
//This program computes for the payment of the employees
for(i=0; i<5; i++){
empHousingAllow[i] = 0.2 * empBasicPay[i];
//This loop statement gets 20% of the employee basic payment
}
System.out.println("Employee Basic and House Rental Allowance");
for(i = 0; i<5; i++){
System.out.println(empBasicPay[i] + " " + empHousingAllow[i]);
//This prints out the final output of the first loop statement
}
}
}
What does the new double[5] do in this statement?

it's not just new double, it is new double[5] which create an array for maximum 5 doubles
as oracle doc explain it well (https://docs.oracle.com/javase/tutorial/java/nutsandbolts/arrays.html)
// declares an array of integers
int[] anArray;
// allocates memory for 10 integers
anArray = new int[10];
// initialize first element
anArray[0] = 100;
// initialize second element
anArray[1] = 200;
so double empHousingAllow[] = new double[5]; allocate memory for an array of five doubles

The new keyword in Java is used to create objects. In this case, the object which is being created is an array containing five doubles.
You might want to have a look at this question, which describes declaration of arrays in greater detail.

Actually the concept required size when you define an array, later you can not change the size.
You can not assign value directly to the memory block like
double d[5];
d[0] = 10.05;
you need to create memory block with specific type.
That's why you need to define an array in that manner.
double d[] = new double[5]
Or
double d[5];
d[0] = new double like that.
then you can add the value to that block.

Related

Updating 2D Array in C

I have to go through each index of a 2d array and find what the neighbor values are and then update the index of the array based on that. My code below does all that but when I have to update the array it updates the existing array so the next index produces the incorrect output. I tried creating a new array but when I use the new array nothing is updated and it stays the same. This is what I have right now.
void ch(int **b, int w, int h)
{
int x,y,i,ct=0;
int **up;
up=malloc(sizeof(int *) * h);
for(i = 0; i<h; i++){
up[i]=malloc(sizeof(int)*w);
}
for (x=0;x<h;x++)
{
for(y=0;y<w;y++)
{
//...Computes Count Here(It Works)
//UPDATE BOARD - Does not update the board
if(b[x][y]==1 && ct<2)
{
up[x][y]=0;
}
else if(b[x][y]==1 && (ct==2 || ct==3))
{
up[x][y]=1;
}
else if(b[x][y]==1 && ct>3)
{
up[x][y]=0;
}
else if(b[x][y]==0 && ct==3)
{
up[x][y]=1;
}
ct=0;
}
}
b=up;
}
I tried updating the 2d array b by doing the changes on itself and it changes the array but it's not the output I am looking for. It changes the output at each iteration so output for other indexes changes but I want it so that another array keeps track of the output so that it does not update the b at every iteration and gives a correct out. What am I doing wrong that is not letting me update the up? What's the best approach to solve this issue?
Make a copy of the original array and use that as a reference. Then you can update your original array directly.
void ch(int **b)
{
int **up = malloc(sizeof(*int)*h);
int i;
for (i = 0; i < w; i++)
{
up[i] = malloc(sizeof(int) * w);
memcpy(up[i], b[i], w * sizeof(int));
}
//
if (up[x][y] == 1)
b[x][y] = 0;
}
// free up
This may be easier to maintain, than having an additional level of indirection as in
void ch(int ***b)
{
int **up = *b;
// do everything else as you intended
// finalize with
*b = up;
// free up
}
Also when making the copy, you can increase the performance a bit by allocating the temporary copy as a linear array
int *up = malloc(sizeof(int) * w * h);
if (up[y * w + x] == 0)
b[y][x] = 1;
C pass arguments by value.
so you can do this way
int* pass(int *p){
//return new pointer; and later assign
}
or get address
void pass(int **p)
{
*p=//new pointer
}
For your situation it is better to modify the same array inside without allocating new
I cannot modify the same array
You can work on copy of array as suggested then update previous array from copy
Or just return that copied array as suggested by me
Worth a look:
C Faq question related on your issue
C Faq ways for allocating multidimensional array
At the end of your function, where you have b=up;, you set b to point to your new array but that only changes your function's copy (b) and not the copy in the calling function... so the caller still sees the original array.
However, since you're using an array of pointers to arrays, rather than actual 2D arrays, you can replace the contents of b (the int *'s to the arrays making up the additional dimension)... and that will avoid having to copy all of your new array's data into the original array.
So instead of:
b=up;
try:
for(i = 0; i < h; i++) {
free(b[i]);
b[i] = up[i];
}
free(up);
That way each row of the original array gets replaced with the corresponding row from the new one, by changing the pointers in the original array of rows.
This is only a good idea, however, if the rows of the original array were dynamically allocated like the ones in your new array were, and if there are no other pointers to the rows floating around (outside of the array of rows passed as b) that might still point to the old memory afterward.

Converting a List to an old-school array of doubles

I am working with a DLL for some hardware that requires old-school arrays as arguments. I'm using Visual C++ Express 2010.
For example, it might have
bool DLLFunction(double* array1, double* array2, int array1length, int array2length);
I'm trying to isolate all that inside a singleton class, so that outside the singleton everything uses Lists and Arrays. That means I have a bunch of wrapper functions that take Lists and then convert them to double[] to pass to the DLL.
As such, I've made the following helper function to convert a List to a double[]. The problem is that the pointer-to-double comes out of the function as undefined.
bool MySingleton::AdaptList(List<double> ^myList, double *myDouble) {
if(myDouble)
delete(myDouble);
myDouble = new double[myList->Count];
for(int k=0; k<myList->Count; k++) {
myDouble[k] = myList[k];
}
return true;
} // AdaptList from List to Double*
In my code, I do something like:
double *oldschool;
List<double>^ myList;
myList = gcnew List<double>;
// a bunch of myList.Add( ) calls to add the data
bool success = AdaptList(myList, oldschool);
// eventually, delete oldschool
Using the debugger, inside the AdaptList function, oldschool holds exactly what it needs. When AdaptList returns control, oldschool shows undefined.
Why did it go out of scope?
Thanks!
Whenever you need an unmanaged pointer to an array it is always worth considering if you can get one from pin_ptr<>. It will temporarily pin the array in memory so it cannot be moved while the native code is using it. Something like this:
List<double>^ list = gcnew List<double>;
//...
pin_ptr<double> p = &list->ToArray()[0];
NativeFunctionTakesDoublePointer(p);
You can't use it if the NativeFunction() stores the pointer since the array will be unpinned when the p variable goes out of scope.
You need to either pass a double pointer to the MySingleton::AdaptList member function:
bool MySingleton::AdaptList(List<double> ^myList, double **myDouble) {
if(*myDouble) delete(*myDouble);
*myDouble = new double[myList->Count];
for(int k = 0; k < myList->Count; ++k) (*myDouble)[k] = myList[k];
return true;
} // AdaptList from List to Double*
or a reference to a pointer:
bool MySingleton::AdaptList(List<double> ^myList, double *&myDouble) {
if(myDouble) delete myDouble;
myDouble = new double[myList->Count];
for(int k = 0; k < myList->Count; ++k) myDouble[k] = myList[k];
return true;
} // AdaptList from List to Double*
Reason: You were passing the 'myDouble' pointer by value and not by reference in member function bool MySingleton::AdaptList.

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);

Dynamic Memory storage issue after realloc - C

For an assignment at school, we have to use structs to make matrices that can store a infinite amount of points for an infinite amount of matrices. (theoretical infinite)
For the assignment I decided to use calloc and realloc. How the sizes for the matrix go is: It doubles in size every time its limit is hit for its points (so it starts at 1, then goes to 2, then 4 and so on). It also doubles in size every time a matrix is added as well.
This is where my issue lies. After the initial matrix is added, and it goes to add the second matrix name and points, it gives me the following:
B???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
B is the portion of it that I want (as I use strcmp later on), but the ? marks are not supposed to be there. (obviously)
I am not sure why it is exactly doing this. Since the code is modular it isn't very easy to get portions of it to show exactly how it is going about this.
Note: I can access the points of the matrix via its method of: MyMatrix[1].points[0].x_cord; (this is just an example)
Sample code that produces problem:
STRUCTS:
struct matrice {
char M_name[256];
int num_points[128];
int set_points[128];
int hasValues[1];
struct matrice_points * points;
} * MyMatrix;
struct matrice_points {
int set[1];
double cord_x;
double cord_y;
};
Setup Matrix Function:
void setupMatrix(){
MyMatrix = calloc(1, sizeof(*MyMatrix));
numMatrix = 1;
}
Grow Matrix Function:
void growMatrix(){
MyMatrix = realloc(MyMatrix, numMatrix * 2 * sizeof(*MyMatrix));
numMatrix = numMatrix * 2;
}
Add Matrix Function which outputs this problem after growing the matrix once.
void addMatrix(char Name, int Location){
int exists = 0;
int existsLocation = 0;
for (int i = 0; i < numMatrix; i++){
if (strcmp(MyMatrix[i].M_name, &Name) == 0){
exists = 1;
existsLocation = i;
}
}
*MyMatrix[Location].M_name = Name;
printf("Stored Name: %s\n", MyMatrix[Location].M_name);
*MyMatrix[Location].num_points = 1;
*MyMatrix[Location].set_points = 0;
*MyMatrix[Location].hasValues = 1;
MyMatrix[Location].points = calloc(1, sizeof(*MyMatrix[Location].points));
}
void addMatrix(char Name, int Location)
char Name represents a single char, i.e. a integer-type quantity. char is just a number, it's not a string at all.
When you do this:
strcmp(..., &Name)
you're assuming that the location where that one character is stored represents a valid C string. This is wrong, there is no reason why this should be the case. If you want to pass a C string to this function, you will need to declare it like this:
void addMatrix(char *Name, int Location)
Then you need to copy that C string into the appropriate place in your matrix structure. It should look like:
strncpy(... .M_name, Name, max_number_of_chars_you_can_store_in_M_Name);
Also these field definitions are strange in your struct:
int num_points[128];
int set_points[128];
int hasValues[1];
This means that your struct will contain an array of 128 ints called num_points, another array of 128 ints calls set_points, and an array of one int (strange) called hasValues. If you only need to store the count of total points and set points, and a flag indicating whether values are stored, the definition should be:
int num_points;
int set_points;
int hasValues;
and correct the assignments in your addMatrix function.
If you do need those arrays, then your assignments as they are are wrong also.
Please turn on all warnings in your compiler.
Try adding '\0' to the end of your data.
*MyMatrix[Location].M_name = Name;
You're copying a single character here, not a string. If you want a string, Name should be defined as char *, and you should be using strcpy.

How to store floats in array to be used later?

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.

Resources