I need to initialize a 2D array in C after dynamically allocating memory for it. I'm allocating memory as follows:
double **transition_mat = (double **) malloc(SPACE_SIZE * sizeof(double *));
for (int i = 0; i < SPACE_SIZE; i++) {
transition_mat[i] = (double *) malloc(SPACE_SIZE * sizeof(double));
}
but then I want to initialize it to a certain 2D array, similar to the way initialization can be done when storing the array on the stack:
double arr[2][2] = {{1.0, 7.0}, {4.1, 2.9}};
However, after allocating memory in the first code segment, trying to do assignment as follows produces an error:
transition_mat = (double **) {{1.0, 7.0}, {4.1, 2.9}};
Does anyone know of a clean way to initialize arrays after malloc'ing memory?
Note: someone suggested that I loop over 0 <= i < SPACE_SIZE and 0 <= j < SPACE_SIZE and assign values that way. The problem with that is that the entries cannot simply be computed from i and j, so that code ends up looking no cleaner than any brute force method.
If you're going to have all the data as literals in the code (to do the initialization), why not just store that as an explicit 2D array to begin with, and be done?
Worst case, do the dynamic allocation and copy from your existing array.
Make it static const inside the function, or at global scope, depending on the access pattern you need.
Related
I am new in whole C programming thing (comming from Java), and honestly its really confusing. Ok to the problem I am trying to allocate contigous chunk of data for my 2D array of strings (Guessing its something like 3D array??). All I have is this i believe contiguous allocation for Array of strings?
Can someone help me out with 2D array please?
And yes I know size before running the program, its defined so ROWS for rows, COLS for columns and NAME for length of string.
char **people = malloc(COLS * sizeof(char *));
people[0] = malloc(COLS * NAME);
for(int i = 1; i < COLS; i++)
people[i] = people[0] + i * NAME;
If you actually know the size of the array before running the program, you don't need to dinamically allocate the memory with malloc, you could create a 2D static array. In your case, as it is a 2D array of strings, it could be declared as char * array[ROWS][COLS], and then you could asign a string to a specific element this way: array[nrow][ncol]="Your String".
C, unlike Java, actually has a concept of multidimensional arrays; so unless there's a specific reason you want a char * * *, you might prefer to write:
char (*people)[COLS][NAME] = malloc(ROWS * sizeof(*people));
which sets people to be a pointer to the first of ROWS dynamically-allocated two-dimensional character arrays.
Due to pointer "decay", where an expression of array type will double as a pointer to the first element of the array, you can use people very much as if it were a char * * *; for example, people[3][4] will point to the string in row 3, column 4. The only restriction is that you can't write something like people[3][4] = ... to suddenly change what string to point to. But it sounds like you don't want to do that, anyway?
Note: the above is assuming that you are intentionally using dynamic memory allocation. However, I do recommend you consider Sizigia's suggestion to use static memory, which is the same sort of storage as is used for global variables. If you write something like
static char people[ROWS][COLS][NAME];
then the memory will be allocated just once, at the start of the program, and reused by all calls to the function that declares it.
You can define a char * using typedef so it's better for you to understand the code. Then all you have to do is to dynamically allocate a 2D array of your defined type (in the example below, I defined it as a "string"):
typedef char * string;
string ** people;
people = malloc(ROWS * sizeof(string));
for(int i = 0; i < ROWS; i++){
people[i] = malloc(COLUMNS * sizeof(char));
}
You can access it using the normal array sintax, people[i][j].
I am using GTK, and I am not sure with malloc() function here. Valgrind gives me a memory leak, what I am doing bad?
at first I create pointer to pointer to pointer to GTK widget, because I need three dimensional array.
GtkWidget*** widgets;
and I am using malloc like this:
widgets = malloc((1)*sizeof(GtkWidget**));
for(i = 0; i<= l-1; i++) // l = 4 in my case
{
widgets[i] = malloc((1)*sizeof(GtkWidget*));
for(j = 0; j<=3; j++) // 4 is number of elements in this dimension
{
widgets[i][j] = malloc((1)*sizeof(GtkWidget));
}
}
and at the end I am doing this:
widgets[0][0] = gtk_menu_item_new_with_label("MyLabel");
gtk_menu_shell_append(GTK_MENU_SHELL(indicator_menu), widgets[0][0]);
my array can be smaller and bigger, so I am using dynamic allocation of array, my maximal array indexes are something like widgets[3][3].
I did not post whole code, because it is pretty long, I sent here just the parts for which was valgrind complaining to. What I am doing bad? thank you.
You're only allocating the size of a pointer, when you mean to allocate an array of pointers.
// this will allocate a single character pointer
char ** ptr = malloc(1 * sizeof(char *));
// this will allocate n character pointers
char ** ptr = malloc(n * sizeof(char *));
So if you want a two dimensional array of dimension NxM, you'll need to allocate an array of size N, then walk through that array from 0 to N-1 and allocate arrays of size M.
What you're doing now is assigning pointers returned from malloc to memory you don't own. Is what you actually want a two-dimensional array of pointers to GtkWidget structures?
Using l as a local variable is not a good idea. It is very easy to make a mistake between l and 1, in some editors they look very much the same.
widgets = malloc((l)*sizeof(GtkWidget**)); //is what you needed
iso
widgets = malloc((1)*sizeof(GtkWidget**));
Over here with syntax highlighting the problem immediately appears.
So another suggestion is to for sure use an editor with syntax highlighting
I plan to create an 2D array of a pointer derived from typedef struct
Let's say the typedef struct is named "Items" and contains mixed variables of strings and integers.
I will declare two intvariables namely typenum and typetotal. These two integers will start off from Zero and adds up when the input data matches with certain function.
In the array,Items *type[][], basically type[][] is Items *type[typenum][typetotal] but I cannot do this since I will declare typenum and typetotal as zero at the declaration part.
I tried initializing the array through Items *type[][] = {{0},{0}} but this generates error.
Any advice? Some told me to use malloc() on this, but I simply do not know how.
*Using Tiny C on Windows
Use dynamic memory allocation.
Items **type;
type = malloc(sizeof (Items *) * typenum);
for (int i = 0; i < typenum; i++)
type[i] = malloc(sizeof Items) * typetotal);
You need to manually free the allocated memory after using the array.
for (int i = 0; i < typenum; i++)
free(types[i]);
free(types);
Here is a tutorial on it: http://www.eskimo.com/~scs/cclass/int/sx9b.html
If typenum and typetotal increase as your program runs be sure to use realloc, which will reallocate more memory and keep the contents. You'll need to allocate the first dimension of the array like this:
myArray = realloc(myArray, sizeof(Items*) * typenum);
and then allocate the second dimension for each of the first:
for(...)
myArray[i] = realloc(myArray[i], sizeof(Items) * typetotal);
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]
I want to create an array of pointers to arrays of 3 floats. What is the correct way to do this?
float *array1[SIZE]; // I think it is automatically allocated
// OR
float **array1 = calloc(SIZE, sizeof(float*));
free(array1);
for (int i = 0; i < SIZE; i++) {
array1[i] = (float[]){0,0,0};
// OR
array1[i] = calloc(3, sizeof(float));
}
Then how would I free the data? I'm pretty sure just free(array1); wouldn't work, so would I free each pointer in the array then free the array, or since I allocated three floats, would I free each float, then each 3 float array, then the whole array???
If you know the array size at compile time (and you do, if SIZE is a compile-time constant), you should just declare a two-dimensional array. You don't need to free this at all (and must not).
float array1[SIZE][3];
You need to use calloc, and to create an array of pointers, only if the dimensions are not known at compile time. In this case, there should be one call to free for each call to calloc. And since you cannot use an array after you free it, you need to free the row arrays before you free array1.
float **array1 = calloc(nrows, sizeof (float *));
for (int i=0; i < nrows; i++)
array1[i] = calloc(3, sizeof(float));
// Use it...
// Now free it
for (int i=0; i < nrows; i++)
free(array1[i]);
free(array1);
Edit: if you won't be rearranging the pointers (to sort the rows in-place, for example), you can do all of this with just one calloc (and one call to free afterwards):
float (*array1)[3] = calloc(3*nrows, sizeof (float));
That's because the number of columns is known at compile-time, and that's all the pointer arithmetic needs to know. Then you can write things like array1[i][j], and you can still pass around array1[i] as if it was a real pointer to a row. C is great that way, take advantage of it!
A general rule is that for each time you call malloc() or calloc() you will need to do a free() call on the returned pointer.
If you want a two dimensional array with compile-time known size, just use a two dimensional array! float val[5][3] is perfectly valid.
If you want a two dimensional array and you don't know it's size during compile-time, you most probably want to use a standard, single diemensional calloc() and an appropriate getter.
#define ARR_COLUMNS 10
#define ARR_ROWS 10
float* arr = calloc (ARR_COLUMNS * ARR_ROWS, sizeof(float));
int get(float* arr, int x, int y) {
if (x<0 || x>= ARR_COLUMNS) return 0;
if (y<0 || y>= ARR_ROWS) return 0;
return arr[ARR_COLUMNS*y+x];
}
void set (int* arr, int x, int y, float val) {
if (x<0 || x>= ARR_COLUMNS) return;
if (y<0 || y>= ARR_ROWS) return;
arr[ARR_COLUMNS*y+x] = val;
}
Of course replace the defines with appropriate variables.
By doing so you will:
save yourself costly allocs and frees
have less fragmented memory
simplify your possible realloc calls
ensure the data is cached better and accessed without the common [x][y] vs [y][x] iteration cache problem.
I want to create an array of pointers to arrays of 3 floats. What is the correct way to do this?
Why do you want an array of pointers to arrays? Wouldn't an array of arrays be sufficient? (Keep in mind that arrays are already pointer-like, they are not passed by value, rather the address of the first element is passed when an array is passed as an argument to a function).
// stack allocation, no need to free
float array[SIZE][3];
for (int i = 0; i < SIZE; i++) {
// do something with array[i][0], array[i][1], array[i][2]
}
Then how would I free the data?
In this case you wouldn't, since the data is stack allocated (will be cleaned up automatically once out of scope). Just remember the rule of thumb is that for every memory allocation you make, a corresponding free is necessary. So if you allocate memory for an array of floats, as in
float* arr = malloc(sizeof(float) * 3); // array of 3 floats
Then you only need to call free on the array that you malloc'd, no need to free the individual floats. If you perform nested allocation as in
// array of length SIZE, consisting of float pointers
float** arr = malloc(sizeof(float*) * SIZE);
// allocate the array of 3 floats at each index
for (int i = 0; i < SIZE; i++)
arr[i] = malloc(sizeof(float) * 3);
Then you will need to perform a free for every malloc, as in
// free the individual arrays
for (int i = 0; i < SIZE; i++)
free(arr[i]);
// free the array of arrays
free(arr);
The lesson to take away here is to avoid dynamic allocation of arrays all-together. Stick with either std::vector or stack-allocated arrays.