void matrixSetSize(double ***pMatrix, int size) {
if (*pMatrix == NULL) { // void matrix
*pMatrix = (double**)malloc(size * sizeof(double*));
for (int i = 0; i < size; i++)
*(*pMatrix + i) = (double*)malloc(size * sizeof(double));
}
else { // resize existing matrix
double **pointer = (double**)realloc(*pMatrix, 2 * size * sizeof(double*));
for(int i = 0; i < size; i++)
pointer[i] = (double*)realloc(*(pMatrix+i), 2 * size * sizeof(double));
for (int i = size; i < 2 * size; i++)
pointer[i] = (double*)malloc(size * sizeof(double));
for(int i = 0; i < size; i++)
free(*(*pMatrix + i));
free(*pMatrix);
*pMatrix = pointer;
}
}
Problem: When I try to realocate the size of the matrix, the code won't work and I don't know why. Can someone explain to me why isn't working?
That does not answer your posted code's problem, but could perhaps help you for your bigger picture:
double (*matrix)[size] = malloc(initial_size * initial_size * sizeof(double));
matrix[0][0] = 42;
matrix[size-1][size-1] = 24;
/* resizing */
double (*new_mat)[new_size] = realloc(matrix, new_size*new_size*sizeof(double));
matrix[0][0] = 42;
matrix[new_size-1][new_size-1] = 24;
/* freeing */
free(new_mat);
Isn't it much simpler?
And it's much, much faster to allocate/free, since it's only one allocation.
And it's much, much faster to use, since:
it's one contiguous memory block, so it's cache-friendly
you directly access the cell, you don't have a data dependency on an intermediate pointer.
Please, when you want a 2D-array, make a 2D-array, not a 1D-array-to-pointers-of-N-1D-arrays.
two caveats: 1) if you want to preserve old data on resizing you need to move it manually and 2) your compiler must support C99.
Two problems:
Consider these lines from the reallocation code:
pointer[i] = (double*)realloc(*(pMatrix+i), 2 * size * sizeof(double));
pointer[i] = (double*)malloc(size * sizeof(double));
In the second you don't allocate as much memory as the reallocation.
After you have reallocated, you free the old data, but it has already been done by the realloc calls.
On an unrelated note, in C you should not cast the result of malloc (or it siblings).
My goal is to dynamically reallocate memory for a two dimensional int array in C. I know there are already several questions about that topic, but unfortunately my code does not run properly and i don't know what is going wrong.
First i am allocating memory:
int n = 10;
int m = 4;
int** twoDimArray;
twoDimArray = (int**)malloc(n * sizeof(int*));
for(int i = 0; i < n; i++) {
twoDimArray[i] = (int*)malloc(m * sizeof(int));
}
And initializing the array with integer numbers:
for(int i = 0; i < n; i++) {
for(j = 0; j < 4; j++) {
twoDimArray[i][j] = i * j;
}
}
Then i use realloc() to reallocate memory dynamically:
int plus = 10;
int newArraySize = n + plus;
twoDimArray = (int**)realloc(twoDimArray, newArraySize * sizeof(int));
I am expecting my aray twoDimArray to be accessible at [10][0] now, but when running
printf("twoDimArray[10][0] = %d\n", twoDimArray[10][0]);
i get an "EXC_BAD_ACCESS" runtime error.
Probably i am missing something rather simple, but since i am new to C and can't figure out my mistake. Any help is appreciated.
reallocating the array of pointers is necessary, but then you have only n values that point to something valid. You need to allocate the rest of the sub-arrays because the newly allocated memory points to unallocated/invalid areas. The error is not from accessing the pointer, but from dereferencing it.
You need to add something like:
for(int i = n; i < n+plus; i++) {
twoDimArray[i] = malloc(m * sizeof(int));
}
(same goes for deallocation: first deallocate the arrays in a loop, then deallocate the array of pointers)
Aside:
assigning the result of realloc directly to the original variable can be a problem if realloc returns NULL. Even if it's rare in those resizing cases (Under what circumstances can malloc return NULL?), you should copy the result in a temp variable, check for NULL, and free the old pointer if reallocation failed.
Do I cast the result of malloc?
I am wondering what is the best way to clean up memory which was already allocated during the failed creation of 2D array.
int** a = (int**)malloc(rows * sizeof(int*));
for (int i = 0; i != rows; ++i)
a[i] = (int*)malloc(columns * sizeof(int));
for (int i = 0; i != rows; ++i)
free(a[i]);
free(a);
The sample code above should work like a charm. However malloc can return null and when it will the code above will not handle the problem. How can we protect such case?
Let's say (int*)malloc(columns * sizeof(int)) returned null for i = 3. We already have allocated space for int** a and a[0], a[1] and a[2].
Here is my current approach. Ugly and not sure if correct. This is why I am asking you for help.
int rows;
int columns;
scanf("%d", &rows);
scanf("%d", &columns);
int** a = (int**)malloc(rows * sizeof(int*));
if (!a)
{
printf("Cannot allocate enough space."); // nothing to clean up here
return 1; // to make example easier
}
int i;
bool arrayCreated = true;
for (i = 0; i != rows; ++i)
{
int* tmp = (int*)malloc(columns * sizeof(int));
if (!tmp) // malloc returned null
{
arrayCreated = false; // let's mark that we need to do some cleanup
break;
}
a[i] = tmp;
}
if (!arrayCreated) // creation failed, clean up is needed
{
for (int j = 0; j <= i; ++j)
free(a[j]);
}
else
{
for (int i = 0; i != rows; ++i)
free(a[i]);
}
free(a);
In short:
As you have different functions used to allocate memory, you'll need to call their counterpart deallocation functions accordingly:
malloc(), calloc() and realloc() need to be deallocated with a call to free()
X* x = new X(); needs to be deallocated with delete x;
X** x = new X[10]; needs to be deallocated with delete[] x;
The idiomatic way in c++ is to use either a container
std::vector<X> x;
or a smart pointer like
std::unique_ptr<X> x = std::make_unique<X>();
to redeem you from caring about the necessary bookkeeping to balance allocation/deallocation operations correctly.
Please notice that this is a theoretical question about error handling in such, specific cases. I want to highlight that first two cases are for C, not C++.
There's no standard error handling defined if you're using the wrong pairs of dynamic memory de-/allocation functions.
As mentioned above they need to pair like described. Anything else calls undefined behavior.
int** b = (int**)calloc(sizeof(int*) * rows, sizeof(int*));
This is not correct, the first parameter of calloc is "number of elements to allocate".
should be
int** b = (int**)calloc(rows, sizeof(int*)); /* No need to cast in C */
What is the safe way for creating multidimensional arrays in C and C++
for such scenarios?
In C (in order to avoid segmentation) a real 2D dynamic array should be declared as
int (*arr)[columns]; /* A pointer to an array of n ints */
and (m)allocated using
arr = malloc(sizeof(int [rows][columns]));
or
arr = calloc(rows, sizeof(int[columns]));
In this way a single call to free(arr); is enough.
I'm not sure about C, but C++; delete[] should suffice.
I have the following code:
int width = 10;
int height = 9;
float** matrix = (float**) malloc(height*sizeof(float));
for (unsigned int i = 0; i < height; i++)
matrix[i] = (float*) malloc(width*sizeof(float));
//This works
matrix[6][0] = 3.0f;
for (unsigned int j = 0; j < width; j++) {
for (unsigned int i = 0; i < height; i++) {
//This fails on [6][0]
matrix[i][j] = 3.0f;
}
}
I am attempting to create a 2D array and initialise it however a segmentation fault is received when setting the value of matrix[6][0] within the loop. What I'm finding very strange is that no error is thrown when I set matrix[6][0] outside of the loop. It's my understanding that a segmentation fault occurs when illegal memory is accessed but I cannot find any reason why different memory is being accessed within the loop. I have even examined the assembly code to find out what's happening but I cannot find the problem.
Update: The code was part of a CUDA program (C++) but my brain was half thinking about C and half about C++, hence why it became a mess.
float** matrix = (float**)(float*) malloc(height*sizeof(float));
Instead of sizeof(float) use sizeof(float *) . You need to allocate memory for height number of float pointers .
So your code goes like this -
float** matrix = malloc(height*sizeof(float *));
Your code produces seg fault while using loop as you don't correct amount of memory for float pointers and you end up accessing invalid memory , thus getting undefined behaviour.
Note- Don't use cast for malloc . And check retrun of malloc.
Here is the refined code:
int width = 10;
int height = 9;
float **matrix = malloc(height * sizeof (float *));
for (size_t i = 0; i < height; i++)
matrix[i] = malloc(width * sizeof(float));
matrix is "a pointer to pointers to floats", while matrix[i] are "pointers to floats".
I want to declare the correct pointer and allocate memory for a two-dimensional array, and correctly pass to a function. I am having trouble getting this to work properly and need help.
Here is my code:
double **podrucje;
podrucje=(double **) malloc (sizeof (double *) *123);
for (i=0;i<(123);i++)
{
podrucje[i]=(double *) malloc (sizeof (double) * 11);
}
for (i=0;i<(123);i++)
{
memset (podrucje[i], 0, 10);
}
But this code doesnt work, it messes up whole my program. So i decided to give up on dynamic allocation and use this:
double podrucje[123][11]={0};
But i dont know how to send it and use it in function...
memset works on per byte basis.
double **podrucje = (double **) malloc (sizeof (double *) * 123);
for (i = 0; i < 123; i++)
{
podrucje[i] = (double *) malloc (sizeof (double) * 11);
memset(podrucje[i], 0, sizeof(double) * 11);
}
if you want to pass it just declare it as such
void function(double podrucje[123][11]) {
...
}
You're best off to use malloc, but allocate the whole array on your second line, so it all gets allocated in contiguous memory. So
podrucje = (double*) malloc (sizeof (double) * 123 * 11);
Then the first loop can go away too. And it looks like you're initializing the array to 0 -- in that case, use calloc instead of malloc, eliminating the second loop.
To index into the array, use things like
double myitem = podrucje [11 * row + col];
You should of course use a define or similar to keep the use of 11 consistent, but that's not the point of this answer.
Write the function argument the same way you wrote the variable definition:
void myfunc(double podrucje[123][11])
{
...
}
double podrucje[123][11];
myfunc(podrucje);
Note that the array is passed "by reference" rather than being copied.
In the following code snippet,
podrucje[i]=(double *) malloc (sizeof (double) * 11);
for (i=0;i<(123);i++)
{
memset (podrucje[i], 0, 10);
}
1) You dont need the extra parenthesis against the numbers 123 and 11
The for loop can be as follows,
for (i = 0; i < 123; i++)
2) Instead of using 123 and 11. Try to define a MACRO and use that instead.
Advantage: The code becomes independent of special numbers and is easily maintainable. Especially in the cases of larger code base.
3) If you read the code, podrucje[i] is allocated a memory of 11 doubles But when you memset you are setting it for only 10 doubles while the last one may or may not consist of garbage. Use calloc here, It not only allocated memory but also initializes the same.
podrucje[i]=(double *) calloc(11,sizeof(double));
Also It could be more helpful if you could tell How exactly is it screwing up your code ?
Example, Code Snippet could help more than just stating its screwing up.
It helps others to investigate and solve the issue.
If you have a modern C compiler (C99 would do) you can even declare real 2D matrices with variable sizes. You don't need to fall back to this awful emulation with pointers.
void myfunc(size_t n, size_t m, double podrucje[n][m])
{
...
}
double (*podrucje)[n] = malloc(sizeof(double[n][m]));
myfunc(n, m, podrucje);
For the function you just have to ensure that the declarations of n and m come first, before the matrix.
There are several ways to dynamically allocate memory for an NxM array. Here are two:
You can declare a pointer to an M-element array, and then malloc N instances of it:
double (*podrucje)[11] = malloc(sizeof *podrucje * 123);
As of C89, you don't need to cast the result of malloc, and the practice is discouraged. Also, note that the operand to sizeof is the expression *podrucje; this gives me the same result as sizeof (double) * 11.
You would index this array as podrucje[i][j] like any other 2D array. podrucje[i] implicitly dereferences the pointer (remember that a[i] is equivalent to *(a + i)) so you don't have to do anything funky with it.
You would use it in a function as follows:
void init(double (*podrucje)[11], size_t rows)
{
size_t i, j;
for (i = 0; i < rows; i++)
for (j = 0; j < 11; j++)
podrucje[i][j] = 0.0;
}
which would be called as
init(podrucje, 123);
The drawback to this method is that the function can only operate on Nx11 arrays; if you're using a C99 compiler or a C2011 compiler that supports variable length arrays, you could specify the number of columns as a runtime variable:
void foo(void)
{
size_t rows = 123, cols = 11;
double (*podrucje)[cols] = malloc(sizeof *podrucje * rows);
if (podrucje)
init(cols, podrucje, rows);
...
}
// cols must be declared before it can be used
// in an array declarator
//
void init(size_t cols, double(*podrucje)[cols], size_t rows)
{
size_t i, j;
for (i = 0; i < rows; i++)
for (j = 0; j < cols; j++)
podrucje[i][j] = 0.0;
}
When you're done with the array, deallocate it as follows:
free(podrucje);
The other approach is to allocate each row separately, as follows:
size_t rows = 123, cols = 11;
double **podrucje = malloc(sizeof *podrucje * rows);
if (!podrucje)
{
// malloc failed; handle allocation error here
}
else
{
size_t i;
for (i = 0; i < rows; i++)
{
podrucje[i] = malloc(sizeof *podrucje[i] * cols);
if (!podrucje[i])
{
// malloc failed; handle allocation error here
}
}
}
And you would use it in a function as follows:
void foo()
{
double **podrucje;
// allocate array as above
init(foo, rows, cols);
...
}
void init(double **podrucje, size_t rows, size_t cols)
{
size_t i, j;
for (i = 0; i < rows; i++)
for (j = 0; j < cols; j++)
podrucje[i][j] = 0.0;
}
When you're finished with the array, deallocate it as follows:
for(i = 0; i < rows; i++)
free(podrucje[i]);
free(podrucje);
The first method allocates memory as a single, contiguous block; the second allocates it in a series of smaller, discontinuous chunks. If your array is especially big or your heap especially fragmented, the first method may fail where the second will succeed. If you're working with a compiler that doesn't support variable-length arrays, the first method is much less flexible, because the number of columns must be specified at compile time.
How could the same indexing method work for both forms?
In the first case, each podrucje[i] is an 11-element array of double; indexing it with j works like any other array. In the second case, each podrucje[i] is a pointer to double. Since a[i] is evaluated as *(a + i), array indexing works on pointer expressions just as well as array expressions.
int print_func(char((*p)[26])[10])
{
int i = 0;
for (i=0; i < 26 ; i++) {
fprintf(stderr, "%02d:%.*s\n", i, 10, p[0][i]);
}
return (0);
}
int main(void)
{
int nrow = 26;
int ncol = 10;
char((*p)[26])[10] = (char((*)[26])[10])(0);
char(*q)[10];
char c = 'a';
int i = 0;
p = (char((*)[26])[10])malloc(sizeof(char) * nrow * ncol);
if ((char((*)[26])[10])0 == p) {
return (-1);
}
for (i=0, q=p[0]; i < nrow ; i++) {
memset(q, c, sizeof(char) * ncol);
c++;
q++;
}
for (i=0,q=p[0] ; i < nrow ; i++) {
fprintf(stderr, "%.*s\n", 10, q);
q++;
}
p[0][8][0]='z';
getchar();
print_func(p);
return (0);
}