I am working on a project that I have made use of Calloc and I am trying to free the memory at the end of my main{} function. However, after the program finishes running and I click on the stop, I get this "proj.exe has triggered a breakpoint."
at this set of codes:
while (freeSpace != NULL) {
free(freeSpace++);
}
Here are my codes for allocating memory:
scanf("%d", &SEG);
BLOCKS = 128 / SEG;
for (int k = 0; k < BLOCKS; k++)
{
memory = (int *)calloc(BLOCKS, sizeof(int));
// handle memory allocation failure
}
for (int i = 0; i < BLOCKS; i++)
{
memory[i] = (int *)calloc(SEG, sizeof(int));
// handle memory allocation failure
}
for (int l = 0; l < BLOCKS+5; l++)
{
//freeSpace = (int*)malloc(l * sizeof(int));
freeSpace = (int *)calloc( BLOCKS + 5, sizeof(int));
// handle memory allocation failure
}
for (int o = 0; o < BLOCKS; o++)
{
memorySpace = (int *)calloc(BLOCKS, sizeof(int));
// handle memory allocation failure
}
`
This is the part where I free my memory:
while (freeSpace != NULL) {
free(freeSpace++);
}
Can someone please assist me?
Its really hard to fix your issue because it seems like that these are only a part of your code or it is a prototype?
The following code only based on some 'guess':
int main()
{
scanf("%d", &SEG);
BLOCKS = 128 / SEG;
int* memory = (int *)calloc(BLOCKS+1, sizeof(int*)); // the last is a 'NULL' pointer
memset(memory, 0, sizeof(int*)*BLOCKS+1);
for (int i = 0; i < BLOCKS; i++)
{
memory[i] = (int *)calloc(SEG, sizeof(int));
// handle memory allocation failure
}
while (memory != NULL) {
free(memory++);
}
}
I think you are misunderstanding how pointers work when allocating arrays. Your very first loop has a memory leak in it because you are changing what I am assuming the "memory" pointer is pointing to.
To allocate an array in C would be like below.
int *bigspace;
bigspace = malloc(20 * sizeof(int));
Here we made the pointer "bigspace" point to a new chunk of memory 20 times the size of an integer which is an array. If you did something like below..
int *bigspace;
bigspace = malloc(20 * sizeof(int));
bigspace = malloc(20 * sizeof(int));
This would be no bueno. We are first making "bigspace" pointer point to a chunk of memory (array of ints) and then we are changing what "bigspace" is pointing to by making it point to a new chunk of memory. This means your first chunk of memory does not have a pointer to it anymore and that memory is leaked!
I think the problem is that the value of freeSpace++ is garbage at the end of your allocated memory.
Free a garbage pointer causes the problem.
Related
I am trying to transpose a 2D char array (in C) of unknown size rows and columns at run time. I use malloc to create the array and for loops to copy the chars form the original array to the new array. I am testing on a sample array of size 9x15 to create an array of 15x9 and the code works until my outer loop i =11 and then crash. In debug mode it shows Exception: Access violation writing to location 0xcdcdcdcd. The original array is read in from a file and is created using the same malloc code and works just fine. I have tried moving the code to main, but get the same exception. I am confused on how it does not create the array properly and would appreciate some input on how to correct the code or trouble shoot the issue better. My code is here
char **dest_grid = malloc(sizeof(char*) * source_col);
if (dest_grid == NULL) {
printf("Memory not assigned\n");
exit(EXIT_FAILURE);
}
else {
for (i = 0; i <= source_row; i++) {
dest_grid[i] = malloc(sizeof(char) * source_row);
}
for (i = 0; i < source_col; i++) {
for (j = 0; j < source_row; j++) {
if (j == source_row) {
dest_grid[i][j] = '\0';
}
else {
dest_grid[i][j] = source_grid[j][i];
}
}
}
}
for (i = 0; i < source_col; i++) {
free(dest_grid[i]);
}
free(dest_grid);
edit: The size of the array is provided from the file when read into memory. Multiple arrays are read in from the file of various sizes.
After char **dest_grid = malloc(sizeof(char*) * src_c); allocates space for src_c pointers, the loop beginning for (i = 0; i <= src_r; i++) attempts to fill it in with src_r+1 pointers, which is wrong.
if (dest_grid == NULL) tests for memory allocation failure, but this is after dest_grid was already used, in assigning values to dest_grid[i].
There is no code to test whether the memory allocations for dest_grid[i] fail.
dest_grid[i][j] = NULL; should be dest_grid[i][j] = '\0';, because NULL represents a null pointer, not a null character, and some definitions of it may cause compiler errors in this use.
free(dest_grid); releases the memory allocated to dest_grid, but the individual allocations to dest_grid[i] have not been freed.
I am using these lines to create variable size matrices:
Temp_Mat_0 = (double **)malloc((M)*sizeof(double ));
for (i=0;i<M;i++)
Temp_Mat_0[i] = (double *)malloc((N)*sizeof(double ));
They are working fine but I keep using them repeatedly in my code. I need to convert them to a function where I pass the pointer and the size. I was not able to do it due to pointers mess.
matrixAllocate(Matrix Pointer,rows,colms)
Can you help!
I think you'd be better off with a very simple scheme that allocates your matrix as a single contiguous block.
double **matrix_alloc(int rows, int cols)
{
/* Allocate array of row pointers */
double ** m = malloc(rows * sizeof(double*));
if (!m) return NULL;
/* Allocate block for data */
m[0] = malloc(rows * cols * sizeof(double));
if (!m[0]) {
free(m);
return NULL;
}
/* Assign row pointers */
for(int r = 1; r < rows; r++) {
m[r] = m[r-1]+cols;
}
return m;
}
This has the added bonus that when you free the matrix you don't need to remember how big it was:
matrix_free( double** m )
{
if (m) free(m[0]);
free(m);
}
As an extension to this, you might declare a struct that also keeps track of the number of rows and columns it has. e.g.
struct matrix {
int rows, cols;
double **m;
};
That makes your matrix functions look a little nicer (i.e. you can pass around struct matrix* instead of double**). It has the added bonus that the matrix dimension travels around with the associated data.
Using one contiguous block for your matrix data is generally preferable unless you have huge matrices. And it's very nice if your matrices are small, because you'll get the benefit of better memory locality in your CPU cache -- that means potential for faster code.
they are working fine
They do not seem really fine. Code should be changed to :
Temp_Mat_0 = malloc((M)*sizeof(double*)); //double* instead of double
if (Temp_Mat_0 == NULL)
return;
for (i = 0; i < M; i++){
Temp_Mat_0[i] = malloc((N)*sizeof(double));
if (Temp_Mat_0[i] == NULL){
free(Temp_Mat_0);
return;
}
}
Then, you can use a function like this :
double ** matrix_pointer = matrixAllocate(rows,colms);
where function matrixAllocate returns the pointer it allocated. For example :
matrixAllocate(rows,colms){
Temp_Mat_0 = malloc((rows)*sizeof(double*));
if (Temp_Mat_0 == NULL)
return NULL;
for (i = 0; i < rows; i++){
Temp_Mat_0[i] = malloc((colms)*sizeof(double));
if (Temp_Mat_0[i] == NULL){
free(Temp_Mat_0);
return NULL;
}
}
return Temp_Mat_0;
}
and call it like :
double **matrix pointer;
matrix pointer = matrixAllocate(rows, colms);
Don't forget to free the malloced memory afterwards.
for (i = 0; i < M; i++){
free(Temp_Mat_0[i]);
}
free(Temp_Mat_0);
Note that you should not cast the result of malloc, and you should also check if malloc was successful.
I am trying to create a 2d array of struct grid_t, and am getting memory leak warnings via address sanitiser, and eventually a seg fault in certain conditions.
There may be various points in my code causing this, but I thought knowing what was going wrong here would point me in the right direction to fixing the rest.
I am new to C and thus to memory management, so all feedback is welcome and appreciated!
void createGridArray(atom_t* ATOM) {
ATOM -> grid = (grid_t**) malloc(WIDTH * sizeof(grid_t*));
grid_t *nullGrid = malloc(sizeof(grid_t));
grid_t temp = {NULL, 0};
*nullGrid = temp;
for (int i = 0; i < WIDTH; i++) {
(ATOM -> grid)[i] = malloc(HEIGHT * sizeof(grid_t));
for (int j = 0; j < HEIGHT; j++) {
(ATOM -> grid)[i][j] = *nullGrid;
}
}
//free(nullGrid); <- do I do this now?
return;
}
Firstly, don't cast the return from malloc(). It is not required in C, and can obscure serious errors.
Second, don't hard-code the type into the malloc() call. For example,
ATOM->grid = (grid_t**) malloc(WIDTH * sizeof(grid_t*));
would be replaced by
ATOM->grid = malloc(WIDTH * sizeof(*(ATOM->grid)));
This ensures the memory allocated is of the required size, regardless of what ATOM->grid is a pointer to.
To answer your question, to release all memory, you need to pass every nonNULL pointer returned by malloc() to free(). Exactly once.
So, if you allocate like this
ATOM->grid = malloc(WIDTH * sizeof(*(ATOM->grid)));
grid_t *nullGrid = malloc(sizeof(*nullGrid));
grid_t temp = {NULL, 0};
*nullGrid = temp;
for (int i = 0; i < WIDTH; i++)
{
(ATOM -> grid)[i] = malloc(HEIGHT * sizeof(*((ATOM->grid)[i])));
for (int j = 0; j < HEIGHT; j++) {
(ATOM -> grid)[i][j] = *nullGrid;
}
the one way of deallocating would be
for (int i = 0; i < WIDTH; i++)
{
free((ATOM -> grid)[i]);
}
free(ATOM->grid);
free(nullGrid);
In this case, you cannot safely free(ATOM->grid) before any free((ATOM -> grid)[i]) (unless you store all of the (ATOM->grid)[i] somewhere else, which sort of defeats the point). The individual (ATOM->grid)[i] may be freed in any order (as long as each is released exactly once).
Lastly, check the pointers returned by malloc(). It returns NULL when it fails, and dereferencing a NULL pointer gives undefined behaviour.
Yes, you need to free(nullGrid); here to avoid a memory leak.
But actually you can simplify your code to this:
void createGridArray(atom_t* ATOM) {
ATOM -> grid = (grid_t**) malloc(WIDTH * sizeof(grid_t*));
grid_t nullGrid = {NULL, 0};
for (int i = 0; i < WIDTH; i++) {
(ATOM -> grid)[i] = malloc(HEIGHT * sizeof(grid_t));
for (int j = 0; j < HEIGHT; j++) {
(ATOM -> grid)[i][j] = nullGrid;
}
}
}
There is need for mallocing nullGrid here at all. BTW the return at the end of a void function is implicit.
You wouldn't do this either:
void Foo()
{
...
int *temp = malloc(sizeof(int));
*temp = ...;
...
bar = *temp;
...
free(temp);
}
but rather:
void Foo()
{
...
int temp
temp = ...;
...
bar = temp;
...
}
The C memory allocation is easier when you think it as a "loan".
Somehow, the system loan you some memory when you call malloc(), and you have to give it back with free().
I'm writing a virtual memory simulator in C, compiling on linux, and I'm getting something rather strange. It takes in a file IO, which I put into an int* plist.
I've printed this "plist" array, and it comes out to
0 100
1 200
2 400
3 300
etc
The problem is that it seems malloc or something is randomly changing plist[3] to 0. It doesn't seem like it should be that way, but I've put a print statement at every line of code to print plist[3], and
tables[i].valid = (char*) xmalloc(num_pages * sizeof(char));
is where it changes. plist[3] = 300 before the line, 0 after it. And it only does this when i = 2. The first 3 rounds of the loop run fine, and on round 3, it changes the values for round 4. I have no idea why, it makes little sense that malloc would change a value in an array that's completely unrelated - is it possible I've gone over some space limit, even though I'm using the heap for basically everything? Would it just change values in random arrays if I did?
for(i = 0; i < 4; i++){
num_pages = plist[i] / P1;
tables[i].page_num = (char**) xmalloc(num_pages * sizeof(char*));
tables[i].valid = (char*) xmalloc(num_pages * sizeof(char));
//initialize page numbers and valid bits
for(j = 0; j < 10; j++){
tables[i].page_num[j] = (char*) xmalloc(16*sizeof(char));
tmp = itoa(i, tmp);
strcat(tables[i].page_num[j], tmp);
strcat(tables[i].page_num[j], "p");
tmp = itoa(j, tmp);
strcat(tables[i].page_num[j], tmp);
tables[i].valid[j] = 0;
}
}
Here's the struct for tables:
typedef struct s_page_table
{
char** page_num;
char* valid;
} t_page_table;
And this is xmalloc (it's just a wrapper to make it easier):
void* xmalloc(int s)
{
void* p;
p = malloc(s);
if (p == NULL)
{
printf("Virtual Memory Exhausted");
exit(1);
}
return p;
}
EDIT: If I take out both lines referencing tables[i].valid, the problem does not exist. plist[3] stays the same. num_pages is always >= 10. I set j to be 0 to 10 just to have less output for debugging purposes.
EDIT 2: If I change valid from a char* to an int* it doesn't work. If I change it to an int, it does.
There are several possibilities, including (but not limited to):
tables[i] is out of bounds;
plist contains a dangling pointer (i.e. it's been deallocated);
plist hasn't been initialised;
plist isn't as large as you think, i.e. plist[3] is out of bounds.
If you can't figure out the problem by looking at the code, valgrind is your friend.
OK. So I believe the problem turned out to be playing with the strings before initializing everything. I'm not entirely certain the reason, maybe someone else can elaborate, but when I encapsulated JUST the initialization in its own function, like only doing mallocs, and then separately created the strings afterwards, the plist variable was unaffected.
For those interested, the encapsulated function looked like this:
t_page_table* table_builder(int* p, int x, int num_tables)
{
t_page_table* ret = xmalloc(num_tables * sizeof(*ret));
int i, tmp, j;
for(i = 0; i < num_tables; i++){
tmp = (p[i]/x);
ret[i].page_num = xmalloc(tmp * sizeof(char*));
ret[i].valid = xmalloc(tmp * sizeof(char));
for(j = 0; j < tmp; j++){
ret[i].page_num[j] = xmalloc(16 * sizeof(char));
ret[i].valid = 0;
}
}
return ret;
}
I've just re-start learning C, but i'm really confused with some memory management details.
I'm getting
pointer being freed was not allocated ... Abort trap
for the code below. Do i really need 1 free per malloc? Why my code is wrong?
Thanks!
#define N 9
typedef struct
{
int MAX_LIST_SIZE;
int length;
int *ini;
}List;
/* allocates new List and its data */
List *newList(int size)
{
List *list = malloc(sizeof(List));
list->MAX_LIST_SIZE = size;
list->length = 0;
list->ini = malloc(sizeof(int) * size);
return list;
}
/* add some value to the list */
void addList(List *list, int val)
{
if (list->length < list->MAX_LIST_SIZE)
list->ini[list->length++] = val;
else
fprintf(stderr, "Error: add(): List is full.\n");
}
/* get an array of N*N lists malloc-ed Lists */
List *gridList()
{
int i, j;
List *cells = malloc(sizeof(List) * N * N);
for (i = 0; i < N * N; i++)
{
/* malloc is called inside NewList()*/
cells[i] = *newList(N);
for (j = 0; j < N; j++)
addList(&cells[i], j + 1);
}
return cells;
}
/* inside main */
List *cells = gridList();
/* use cells ... */
/* free */
for (i = 0; i < N * N; i++)
{
free(cells[i].ini);
/* line below causes CRASH */
free(&cells[i]);
}
You do :
cells[i] = *newList(N);
which sets each element in cells to a copy of the list dynamically allocated by newList. So newList dynamically allocates a list, then you take the pointer to that dynamically allocated List, dereference it, and copy it into cells[i]. So then later on when you go to free() each element:
free(&cells[i]);
It doesn't work because each element in cells[i] is a List, not a List * (list pointer) allocated by malloc().
So you have two options. One (bad one) is to just remove that last free() line since there's nothing to free. However, this just covers up a larger problem which is that you now have memory leaks because you can't go back and free the dynamically allocated Lists created with newList().
Instead it's likely you want to have an array of pointers to the lists, which you can do by changing it to:
List **cells = malloc(sizeof(List*) * N * N);
so that cells[i] refers to a List *. newList() returns such a pointer, so you would change that line to:
cells[i] = newList(N);
similarly, addList() takes such a pointer, so you'd simply change that line to:
addList(cells[i], j + 1);
since &cells[i] would pass it the address of the pointer, which is not what you want.
Finally, change the free statements to:
free(cells[i]->ini); // ->init because cells[i] is now a pointer to a List, List *
free(cells[i]);
The problem is you are allocating an array of lists, copying the full contents of your lists into the array elements, and then trying to free them. The original allocated List records are a memory leak, and the free calls are indeed trying to free memory that was not malloc'ed (or more exactly were malloc'ed in a single big block).
You want an array of pointers to pointers to hold your lists:
/* get an array of N*N lists malloc-ed Lists */
List **gridList()
{
int i, j;
// VV note change here
List **cells = malloc(sizeof(List*) * N * N);
for (i = 0; i < N * N; i++)
{
/* malloc is called inside NewList()*/
cells[i] = newList(N); // << Note change here.
for (j = 0; j < N; j++)
addList(cells[i], j + 1);
}
return cells;
}
/* free */
for (i = 0; i < N * N; i++)
{
free(cells[i]->ini); // << and here
/* line below causes CRASH */
free(cells[i]); // << and here
}
free(cells);