why can't i free the memory? - c

I wrote a simple counter structure in C:
typedef struct{
int value;
}Counter;
then, I wrote some simple implementations:
void createCounter(Counter *dCount)
{
dCount = (Counter*)malloc(sizeof(Counter));
dCount->value = 0;
}
void FreeResource(Counter *dCount)
{
free(dCount);
}
now in the main, i wanted to free the pointer i created and it complained that the pointer being freed was not allocated.I am looking at the code and I thought I allocated memory for it when I called the createCounter() function?
int main()
{
Counter m;
CreateCounter(&m);
FreeResource(&m); //run time error given here..
return 0;
}

You are trying to pass the address of a variable allocated in stack and then trying to assign an address allocated by malloc to it which won't get reflected in the caller. So, when you try to free it, you are effectively passing a stack variable's address to free due to which you get undefined behavior.
Change the function
void createCounter(Counter *dCount)
{
dCount = (Counter*)malloc(sizeof(Counter));
dCount->value = 0;
}
as
void createCounter(Counter **dCount)
{
*dCount = (Counter*)malloc(sizeof(Counter));
(*dCount)->value = 0;
}
In your case, the pointer gets passed by value and the new memory address allocation doesn't reflect in the caller.
The main function must be changed as:
int main()
{
Counter *m;
CreateCounter(&m);
FreeResource(m); //run time error given here..
return 0;
}

dCount = (Counter*)malloc(sizeof(Counter));
There are multiple problems:
dCount = ... has absolutely no effect for the caller., i.e. the pointer is unchanged.
You passed a pointer to an already allocated structure, you don't need to malloc anything
You're trying to free something (&m) you didn't obtain from malloc
The only sane suggestion at this point is to review a chapter on pointers.

The problem is that in CreateCounter the variable dCount is a local variable. That means changes to the variable won't be visible when the function returns.
There are two common solutions to this:
Return the pointer:
Counter *CreateCounter()
{
Counter *dCounter = malloc(sizeof(Counter));
dCounter->value = 0;
return dCounter;
}
Pass the argument as a reference, i.e. a pointer to the pointer:
void CreateCounter(Counter **dCounter)
{
*dCounter = malloc(sizeof(Counter);
(*dCounter)->value = 0;
}
And call it as this:
Counter *m;
CreateCounter(&m);

Related

Save pointer to array in struct

Save pointer to array in struct.
I would like to store the pointer to array of int into struct but I am having trouble.
Below my code with commentaries:
typedef struct _index {
int *data;
} Index;
void adder(struct _index *s){
int i;
int arr[maxint];
for(i=0; i<maxint; i++) {
arr[i] = i+42;
}
//i got a gibberish
//s->data = arr;
//works fine
s->data = (int *) malloc(maxint * sizeof(int));
s->data = memcpy(s->data, arr, maxint * sizeof(int));
)
int main() {
Index n;
int i;
//this method also works.
//int arr[maxint];
//for(i=0; i<maxint; i++) {
// arr[i] = i+42;
//
//}
//n.data = arr;
adder(&n);
for(i=0; i<maxint;i++) {
printf("%d-", n.data[i]);
}//testing
return 0;
}
when i make assignment, i got strange numbers:
117-118-119-120-12-0-22-2292964-0-2293008-127-0-129-130-131-0-0-0-0-0-0-138-0
but if i use malloc and memcpy all works fine
You got gibberish in your first case, because you tried to "return" the address of a local variable from a function through the pointer. Once the function finishes execution, the int arr[maxint]; won't be valid. In other words, after adder() finishes execution, int arr[maxint]; goes out of scope and it's lifetime is over. So, the (returned) pointer becomes invalid and using that further in the caller function will result in undefined behaviour.
Solution:
As you've done correctly, using dynamic memory.
use static variable (not a good approach, but possible).
In both the aforesaid approach, the lifetime of the variable ( static arr array/ malloc()ed memory) is not limited to function scope and thus, the pointer to the meory will be vaild in the caller function.
The array arr in the adder() function is on the stack and only exists as long as the code in that function is running. Once adder() returns that memory is re-used by the rest of the program and its content overwritten.
int arr[] is placed on the stack and gets removed from the stack when it goes out of scope. So you will point to garbage.
It works fine if you include it in your main because that way it hasn't gone out of scope yet.
Malloc works because you allocate memory and not just place it on the stack.

Unable to modify pointer variable passed as argument to a function

I have this function
int rt_exist(struct route_entry* prev_rte) {
prev_rte = rte_head; //This doen't assigns rte_head to prev_rte
return 0;
}
where rte_head is an initialized struct route_entry* pointer variable.
But in the above case "prev_rte" is not assigned the value of rte_head.
By the way ,I if I do something like this
int rt_exist(struct route_entry* prev_rte) {
struct route_entry* rte_new;
rte_new = rte_head; //But this can
return 0;
}
The above assignment occurs smoothly . The problem arises when pointer variable is passes as function argument.
It's a weird question with little details ,but can someone point me to a possible direction or something wrong I might be doing.
Consider this:
void foo (int j)
{
j = 7;
}
foo (8);
What do you expect to happen here? A function can't change a value in the caller this way.
What should happen here:
rt_exist (NULL);
For C++, you can use references:
int rt_exist(struct route_entry*& prev_rte) {
prev_rte = rte_head; //This doen't assigns rte_head to prev_rte
return 0;
}
For C, you need to pass a pointer to the thing you want to change:
int rt_exist(struct route_entry** prev_rte_ptr) {
*prev_rte_ptr = rte_head; //This doen't assigns rte_head to prev_rte
return 0;
}
Yes! in first case you are using temporary portion of a stack. But in the second case you are using allocating. Which means that you are using a portion of memory which is from heap. It will obviously affect the value. This is like a new variable in a new block. In this scope it will have the assigned value.
But in rt_exist the copy of the variable is passed. So any change in that will not affect the actual one. But you can pass it's address and change it easily like this.
int rt_exist(struct route_entry** prev_rte)
{
*prev_rte = rte_head; //This does assign rte_head to prev_rte.
return 0;
}

Changing arrays inside a function in C w/o a pointer using memory addresses

While learning about pointers, arrays and functions on tutorials point I realised that I could achieve my goal of returning an array from a function by creating a new array in the main function, creating a pointer and assigning the return value of the function to this pointer and then using a for loop in the main function incrementing the pointer to reassign the values of the array to the array internal to the sorting function.
However I was wondering since the memory is returned to the stack after the function returns how come the values in the array aren't reassigned to something else and secondly is there a way I could using memory addresses change the actual array in the main function inside the sorting functions and then return void? I am using a bubble sort algorithm, this is my current sorting function;
#include <stdbool.h>
int *arr_sort(int *arr){
int *ptr = arr;
bool flag = true;
while(flag){
flag = false;
int i = 0;
for(i;i<4;i++){
if(arr[i]>arr[i+1]){
flag = true;
arr[i]+=arr[i+1];
arr[i+1] = arr[i]-arr[i+1];
arr[i]-= arr[i+1];
}
// printf("%d : %d\t%d : %d \n",i,arr[i],i+1,arr[i+1]); *Included to display the values as they are being switched
}
printf("\n\n");
}
return arr;
}
Then the for loop in the main that assigned my array (called unsorted_array) to the pointer as it is incremented through the array created inside the sorting function
ptr = arr_sort(unsorted_array);
for(j;j<5;j++){
unsorted_array[j]=*(ptr+j);
The whole thing works as a program but I was just wondering in the interest of building up knowledge (Haven't been programming in C for long), is there a better way to do this?
No need to return array from your function. Just define your function as
void arr_sort(int *arr){
bool flag = true;
while(flag){
flag = false;
int i;
for(i = 0; i < 4; i++){
if(arr[i] > arr[i+1]){
flag = true;
arr[i]+=arr[i+1];
arr[i+1] = arr[i]-arr[i+1];
arr[i]-= arr[i+1];
}
}
printf("\n\n");
}
}
Any and all changes to arr will be made to the array in main.
I assume that you, with "creating a new array in the main function" mean something like this:
int main(int argc, const char *argv[])
{
char unsorted_array[ARRAY_SIZE];
// ... Code
}
Any variable, (trivial, pointer or array) located on the stack is kept while calling another function, but any variable located on the stack by the called function is invalidated when the function returns.
But: a pointer located on the stack may point to an array on the heap. That is if the array is either allocated by malloc(), being declared as static inside the function, or being a global variable. In that case, the content of the array is of course kept as the function returns, and can be made available to the calling function by e.g returning the pointer. Only the pointer (e.g. typically 4 bytes) is copied to the calling function stack as the function returns, not the array which the pointer points to.
Similarly, an array located on the stack may be made available to a called function, by supplying the called function with a pointer to the array, just as you do. What is copied to the called function's stack, is only the pointer (4 bytes), hence the called function may access and modify the array, and the array itself is not invalidated as the function returns.
NB: in C, when invoking a function declared as
void afun(char anarray[ARRAY_SIZE);
the compiler implicitly treats the function as if it was declared as
void afun(char *anarray);
i.e. calling afun only copies the pointer, not the array to the called function's stack.

How to push elements into a stack using an array of void* as data structure?

Lately I've been writing code in C for a generic stack using an array of void pointers. After doing some tests everything seemed to be fine, until this last test:
while(i < 9) {
push_pila(mi_pila,(int*)&i);
i++;
}
As you can see I'm passing an i as an argument into the push_pila function. This is the code for the push_pila function in the stack:
typedef struct {
void **vec;
int tope;
int16_t max_elementos;
}PILA;
int push_pila(PILA *mi_pila,void *val) {
if(pila_llena(mi_pila)) {
return -1;
}
else {
mi_pila->tope = mi_pila->tope + 1;
mi_pila->vec[mi_pila->tope] = val;
return 0;
}
}
Here is where the problem is, because my stack is an array of void* containing the values of the address of val. When I pass the value of i I'm passing the address of it. The problem in this case is that all the values inside the stack will contain the same address therefore all the value in the stack will be the same, so when I pop the stack using the pop function I will return the same value which is the last value of i, in my case 9.
Is there any solution to this problem?. Or is just that this is not the best way to push elements in the array?
If you want to pass in memory values, you need to make each entry have a distinct memory value, rather than incrementing the same address over and over again and passing the same address. You need to allocate memory from the heap with malloc, set that memory to whatever integer value you want (1-9 in this case), and then push that pointer onto the stack.
Something like this:
while(i < 9) {
int* int_ptr = (int*) malloc(sizeof(int));
*int_ptr = i;
push_pila(mi_pila, int_ptr);
i++;
}
Later, when you're done with the stack, you will need to pop off each pointer and free it.
You must allocate fresh storage to hold each integer:
while(i < 9) {
int *i_boxed = safe_malloc(sizeof(int));
*i_boxed = i;
push_pila(mi_pila, i_boxed);
i++;
}
Note safe_malloc just calls malloc and handles allocation failure gracefully.

Modifying struct members through a pointer passed to a function

for instance this code:
struct test{
int ID;
bool start;
};
struct test * sTest;
void changePointer(struct test * t)
{
t->ID = 3;
t->start = false;
}
int main(void)
{
sTest->ID = 5;
sTest->start = true;
changePointer(sTest);
return 0;
}
If I was to execute this code, then what would the output be? (i.e. if I pass a pointer like this, does it change the reference or is it just a copy?)
Thanks in advance!
Your program doesn't have any output, so there would be none.
It also never initializes the sTest pointer to point at some valid memory, so the results are totally undefined. This program invokes undefined behavior, and should/might/could crash when run.
IF the pointer had been initialized to point at a valid object of type struct test, the fields of that structure would have been changed so that at the end of main(), ID would be 3. The changes done inside changePointer() are done on the same memory as the changes done in main().
An easy fix would be:
int main(void)
{
struct test aTest;
sTest = &aTest; /* Notice the ampersand! */
sTest->start = true;
changePointer(sTest);
return 0;
}
Also note that C before C99 doesn't have a true keyword.
The only question is why do you need a test pointer in a global name space? Second is that you do not have any memory allocation operations. And you have a pointer as an input parameter of your function. Therefore structure where it points to will be changed in "changePointer".
1) First thing your code will crash since you are not allocating memory for saving structure.. you might need to add
sText = malloc(sizeof(struct test));
2) After correcting the crash, you can pass structure pointer and the changes you make in changePointer function will reflect in main and vizeversa..
3) But since you are not printing anything, there wont be any output to your program..

Resources