calculate2 essentially does matrix calculation based on neighbors. I haven't written C in a while and I was wondering if the memcpy at every iteration was going to be a problem for memory or if I should free the tmpMatrix after every k iteration before doing a new memcpy?
void transform2(int *pMatrix, int iteration)
{
if(iteration == 0)
return;
int fullLength = MATRIX_DIM * MATRIX_DIM;
int tmpMatrix[fullLength];
int start;
int row;
int col;
for(start = 0; start < iteration ; start++)
{
memcpy(tmpMatrix, pMatrix, sizeof(pMatrix[0]) * (fullLength));
for(row = 0; row < MATRIX_DIM ; row++)
{
for(col = 0; col < MATRIX_DIM ; col++)
{
int res = calculate2(pMatrix, tmpMatrix, row, col , iteration);
set_at(pMatrix, res, row, col);
}
}
}
}
Also, I'm open to suggestions if you guys think there's a cleaner way of handling this. Essentially the tmpMatrix is the previous matrix at iteration-1.
P.S pMatrix is a global int *_Matrix declaration and I use free() at the end of my main for that one.
memcpy does not do memory allocation, so it cannot cause a memory leak by itself 1. Your allocation of tmpMatrix is done in the automatic storage (AKA "on the stack"), so it is not leaked in your method.
In general, you should watch out for memory leaks when you call malloc, calloc, realloc, strdup, and functions that return pointers to memory blocks that have been allocated dynamically.
1 Copying data into a memory block of pointers may leak the blocks pointed to by these pointers, but not the argument that you pass to memcpy.
memcpy does not allocate memory (in the sense of permanently, at the destination), so your code will not leak memory due to memcpy.
i have not checked your code otherwise, though.
Related
I am starting to learn dynamic memory allocation. In this code, I have created in main function 2d array:
int r, c;
scanf("%d %d\n", &r, &c);
size_t row = (size_t) r;
size_t col = (size_t) c;
int **board = malloc(row * sizeof(*board));
for (int i = 0; i < r; i++) {
board[i] = malloc(col * sizeof(*board[i]));
}
(I need both int and size_t because of for loops, especially when r>=0, which is always true for size_t).
Then I change the board with other functions. Valgrind returs:
==59075== 364 (56 direct, 308 indirect) bytes in 1 blocks are definitely lost in loss record 2 of 2
==59075== at 0x483577F: malloc (vg_replace_malloc.c:299)
==59075== by 0x10B4DB: main (name22.c:122)
==59075==
122 line is:
int **board = malloc(row*sizeof( *board));
I suppose I have to use free(), but after checking other answers I don't know, where is my mistake and where to put free(), if use use this table through the rest of the program. I would appreciate your hints and explanations.
`
When you call int **board = malloc(row * sizeof(*board)); , the system will allocate you row * sizeof(*board) bytes of memory and then return a pointer to the start of that memory (ie - a memory address), which you are storing in the int ** variable called board.
When your program finishes, the system will reclaim that memory, so if your program is short lived, it probably doesn't matter very much, but it's good practise to get into the habit of freeing your memory because it will not reclaim any memory at all until your program exits, unless you tell it to.
For that reason, you should always call free(...), passing in the memory address you were given when you first called malloc(...), once you are done with that memory. In most cases, each call to malloc(...) should have an equal and opposite call to free(...)
This is important because your system has a finite amount of memory. If your program is asking for resources and then never giving them back when they are done you will eventually run out of memory - this is what is called a "memory leak".
So for you, calling free(...) correctly, is going to look something like this:
int **board = malloc(row * sizeof(*board));
for (int i = 0; i < r; i++) {
board[i] = malloc(col * sizeof(*board[i]));
}
// Do something with board
for (int i = 0; i < r; i++) {
free(board[i]);
}
free(board);
I am unsure if I am using the realloc function correctly.
In my program, I first ask the user for the size of the array and allocate memory for it using malloc, then initialise it with some values.
Then I want to make the same array twice it's size, using realloc. Here is my code. Am I using realloc to resize int *A correctly?
#include <stdio.h>
#include <stdlib.h>
int main(){
int n;
printf("Enter size of array\n");
scanf("%d", &n);
int *A = (int*)malloc(n*sizeof(int)); //dynamically allocated array
for (int i = 0; i < n; i++) //assign values to allocated memory
{
A[i] = i + 1;
}
A = (int*)realloc(A, 2*sizeof(int)); //make the array twice the size
free(A);
}
When using malloc() , don't cast the return value as said here
You are not using the right size. In hereint *A = (int*)malloc(n*sizeof(int)); the size given to malloc is n*sizeof(int). If you want twice that size, you should call realloc() with n*sizeof(int)*2 instead of 2*sizeof(int)
Handle realloc() failure. In case realloc(A, new_size) fails, A == NULL and you will have memory leak. So, use a different pointer B, check if (B != NULL) and then assign A = B (old_size = new_size). If B == NULL deal with the allocation fail
In this case it's easier to double the n before malloc so you don't have the use realloc, because you know, that you gonna double the arraysize. Using realloc can slow the working of the program, because if you make it longer, and the adresses after the currently allocated memories aren't free, then the whole array will be moved. Also you have the change the last line as it was suggested before me.
I am relatively new to C and have coded (or more precise: copied from here and adapted) the functions below. The first one takes a numpy array and converts it to a C int array:
int **pymatrix_to_CarrayptrsInt(PyArrayObject *arrayin) {
int **result, *array, *tmpResult;
int i, n, m, j;
n = arrayin->dimensions[0];
m = arrayin->dimensions[1];
result = ptrvectorInt(n, m);
array = (int *) arrayin->data; /* pointer to arrayin data as int */
for (i = 0; i < n; i++) {
result[i] = &array[i * m];
}
return result;
}
The second one is used within the first one to allocate the necessary memory of the row vectors:
int **ptrvectorInt(long dim1, long dim2) {
int **result, i;
result = malloc(dim1 * sizeof(int*));
for (i = 0; i < dim1; i++) {
if (!(result[i] = malloc(dim2 * sizeof(int)))){
printf("In **ptrvectorInt. Allocation of memory for int array failed.");
exit(0);
}
}
return result;
}
Up to this point everything works quite fine. Now I want to free the memory occupied by the C array. I have found multiple threads about how to do it, e.g. Allocate and free 2D array in C using void, C: Correctly freeing memory of a multi-dimensional array, or how to free c 2d array. Inspired by the respective answers I wrote my freeing function:
void free_CarrayptrsInt(int **ptr, int i) {
for (i -= 1; i >= 0; i--) {
free(ptr[i]);
}
free(ptr);
}
Nontheless, I found out that already the first call of free fails - no matter whether I let the for loop go down or up.
I looked for explenations for failing free commands: Can a call to free() in C ever fail? and free up on malloc fails. This suggests, that there may have been a problem already at the memory allocation. However, my program works completely as expected - except memory freeing. Printing the regarded array shows that everything should be fine. What could be the issue? And even more important: How can I properly free the array?
I work on a Win8 64 bit machine with Visual Studio 10 64bit compiler. I use C together with python 3.4 64bit.
Thanks for all help!
pymatrix_to_CarrayptrsInt() calls ptrvectorInt() and this allocation is made
if (!(result[i] = malloc(dim2 * sizeof(int)))){
then pymatrix_to_CarrayptrsInt() writes over that allocation with this assignment
result[i] = &array[i * m];
causing a memory leak. If array is free()'d then attempting to free() result will fail
I wrote a C code that usea a matrix of double:
double y[LENGTH][4];
whith LENGTH=200000 I have no problem.
I have to increase the numbers of rows to LENGTH=1000000 but when I enter this value and execute the program it returns me segmentation fault.
I tried to allocate more memory using malloc:
double **y = (double **)malloc(LENGTH * sizeof(double*));
for(int i = 0; i < LENGTH; i++){
y[i] = (double *)malloc(4 * sizeof(double));
}
I run the the code above and after some second of calculations it still gives me "segmentation fault".
Could anyone help me?
If you want a dynamic allocated 2D array of the specified row-width, just do this:
double (*y)[4] = malloc(LENGTH * sizeof(*y));
There is no need to malloc each row in the matrix. A single malloc and free will suffice. Only if you need dynamic row width (each row can vary in width independent of others) or the column count is arbitrary should a nested malloc loop be considered. Neither appears to be your case here.
Notes:
Don't cast malloc in C programs
Be sure to free(y); when finished with this little tryst.
The reason your statically allocated array is segfaulting with a million elements is (presumably) because it's being allocated on the stack. To have your program have a larger stack, pass appropriate switches to your compiler.
ProTip: You will experience less memory fragmentation and better performance if you flip your loop around, allocating
(double *)malloc(LENGTH * sizeof(double));
four times. This will require changing the order of your indices.
I ran the the code with this definition and after some second of calculations it still gives me "segmentatin fault"
If you're getting a segmentation fault after allocating the memory, you're writing outside of your memory bounds.
I run this code
#include <stdio.h>
#include <stdlib.h>
// We return the pointer
int **get(int N, int M) /* Allocate the array */
{
/* Check if allocation succeeded. (check for NULL pointer) */
int i, **table;
table = malloc(N*sizeof(int *));
for(i = 0 ; i < N ; i++)
table[i] = malloc( M*sizeof(int) );
return table;
}
void free2Darray(int** p, int N) {
int i;
for(i = 0 ; i < N ; i++)
free(p[i]);
free(p);
}
int main(void)
{
const int LENGTH = 1000000;
int **p;
p = get(LENGTH, 4);
printf("ok\n");
free2Darray(p ,LENGTH);
printf("exiting ok\n");
return 0;
}
and it was executed normally.
I got the code from my pseudo-site.
You should not cast what malloc returns. Why?
Also notice, that since you need a dynamic allocation only for the number of rows, since you know the number of columns. So, you can modify the code yourself (so that you have some fun too. :) )
I hope you didn't forget to **free** your memory.
I'm having some issues with producing an int matrix without creating memory leaks. I want to be able to make a given (global) matrix into any size dynamically via read_matrix(). But then i want to be able to free the memory later on. So in my main method the second printf should result in a bus error since it should not have any memory allocated to it. How would i go about creating this?
int** first_matrix;
int** second_matrix;
int** result_matrix;
int** read_matrix(int size_x, int size_y)
{
int** matrix;
matrix = calloc(size_x, sizeof(int*));
for(int i = 0;i<size_x;i++) {
matrix[i] = calloc(size_y, sizeof(int));
}
for(int i = 0;i<size_x;i++) {
for(int j = 0;j<size_y;j++) {
matrix[i][j] = i*10+j;
}
}
return matrix;
}
int main(int stackc, char** stack)
{
first_matrix = read_matrix(10,10);
printf("9:3 %d - 4:6 %d \n", first_matrix[9][3], first_matrix[4][6]);
free(*first_matrix);
free(first_matrix);
printf("9:3 %d - 4:6 %d \n", first_matrix[9][3], first_matrix[4][6]);
}
Just because the memory has been free'd doesn't mean you can't access it! Of course, it's a very bad idea to access it after it's been free'd, but that's why it works in your example.
Note that free( *first_matrix ) only free's first_matrix[0], not the other arrays. You probably want some kind of marker to signify the last array (unless you will always know when you free the outer array how many inner arrays you allocated). Something like:
int** read_matrix(int size_x, int size_y)
{
int** matrix;
matrix = calloc(size_x, 1+sizeof(int*)); // alloc one extra ptr
for(int i = 0;i<size_x;i++) {
matrix[i] = calloc(size_y, sizeof(int));
}
matrix[size_x] = NULL; // set the extra ptr to NULL
for(int i = 0;i<size_x;i++) {
for(int j = 0;j<size_y;j++) {
matrix[i][j] = i*10+j;
}
}
return matrix;
}
Then when you're freeing them:
// keep looping until you find the NULL one
for( int i=0; first_matrix[i] != NULL; i++ ) {
free( first_matrix[i] );
}
free( first_matrix );
You need to free each row individually:
void free_matrix(int **matrix, int size_x)
{
for(int i = 0; i < size_x; i++)
free(matrix[i]);
free(matrix);
}
Freeing the memory doesn't make it go away, it just means that another allocation might grab that same chunk of memory. Whatever you put in it will still be there until something else overwrites it.
Also, you're not freeing everything you allocated. You're only freeing the array of pointers and the first row. But even if you free everything correctly, you would still have the same effect.
If you want to create a "bus error" you need to point to memory that doesn't belong to your process. Why do you want to do that anyway?
You only freed the first row (or column) of first_matrix. Write another function like this:
void free_matrix(int **matrix, int rows)
{
int i;
for(i=0; i<rows; i++)
{
free(matrix[i]);
}
free(matrix);
}
You might want to make the matrix into a struct to store it's row and column count.
I recommend using valgrind to track down unfree'd memory, as opposed to trying to make a bus error occur. It rocks for lots of other stuff as well.
Sam
You're getting memory leaks because you're freeing the first row of the matrix and the list of rows, but none of the 1 to nth rows. You need to call free in a loop.
There are a couple of alternatives, however:
- Allocate sizeof(int*)rows + rowscols*sizeof(int) bytes and use the first bytes for the row pointers. That way, you only have a single chunk of memory to free (and it's easier on the allocator, too)
- Use a struct that contains the number of rows. Then you can avoid the row list altogether (saving memory). The only downside is that you have to use a function, a macro, or some messy notation to address the matrix.
If you go with the second option, you can use a struct like this in any C99 compiler, and again only have to allocate a single block of memory (of size numints*sizeof(int)+sizeof(int)):
struct matrix {
int rows;
int data[0];
}
The concept you are missing here, is that for every calloc, there must be a free.
and that free must be applied to the pointer passed back from calloc.
I recommend you create a function (named delete_matrix)
that uses a loop to free all of the pointers that you allocate in here
for(int i = 0;i < size_x;i++) {
matrix[i] = calloc(size_y, sizeof(int));
}
then, once that is done, free the pointer allocated by this.
matrix = calloc(size_x, sizeof(int*));
The way you are doing it now,
free(*first_matrix);
free(first_matrix);
won't do what you want it to do.