Local Variables with Pointer Casting - c

One of the issues I am having is attempting to cast variables into memory to be accessed at later points.
I have an example code here that works perfectly:
unsigned int *label = (unsigned int *)malloc(sizeof(unsigned int));
label = (unsigned int * ) 0xFFAAFFAA;
Anywhere else in my code I can access this value label, and it will be pointing to 0xFFAAFFAA as its value when I try to print it.
However, if I try to assign from a variable like such:
//all of this is inside a method.. so any variables declared would be local
unsigned int localVariable = 0xFFFFFFFF;
unsigned int *label = (unsigned int *)malloc(sizeof(unsigned int));
label = &localVariable;
The result will be something crazy like: 0x7f252d6b5f00 .. which I am just assuming is some random address in memory. I know this issue is because of a local variable as that operates within a function and is not global. But I can't figure out what the syntax of this would be...
The reason I want to define the local variable is because there is other logic in the function to add and subtract from that variable.. I left it out to keep it minimal
EDIT: so I could do something like this?
unsigned int localVariable = 0xFFFFFFFF;
unsigned int *label = (unsigned int *)malloc(sizeof(unsigned int));
*label = localVariable;

It sounds like what you want here is to create a pointer to a variable in a function then have it accessible outside of the function.
The issue with your first example is that you allocate memory and assign its address to label, but then you overwrite the value of label causing you to loose the reference to the memory you just allocated. You need to dereference the pointer using the * operator to write to the memory address you just allocated.
The second example won't work because you take the address of a local variable, then that variable goes out of scope when the function returns. So the address becomes invalid.
The below example allocates space, dereferences the pointer just allocated to write to the given address, then the address is returned to the caller.
unsigned int *func()
{
// allocate space (don't cast return value of malloc)
unsigned int *label = malloc(sizeof(unsigned int));
// dereference pointer and write value to allocated memory
*label = 0xFFAAFFAA;
// pass pointer to allocated memory to the calling function
return label;
}
Keep in mind that the calling function will be responsible for calling free on the memory that is returned when it is done using it to avoid a memory leak.

Related

Passing struct pointer to two functions and then calling malloc

I have a struct in my main function. I pass that pointer to another function which does some stuff and if conditions are met, it passes it to another function to get filled out. When returning to the main function the t struct contains none of the data mydata that was copied into it.
typedef struct _t {
int one;
int two;
int three;
int four;
} T;
void second(T *t) {
t = malloc(20);
memcpy(t, mydata, 20);
}
void first(T *t) {
second(t);
}
int main() {
T t;
first(t);
}
Do I need to be working with double pointers here? If the address of t was 0x1000 and I passed it to first() then wouldn't referencing t just be 0x1000? And same as if I pass the pointer to second()?
In this answer, I assume that, for reasons not shown, you do in fact need to make a dynamic memory allocation. If that is not the case, the only changes that need to be made are replacing first(t); with first(&t);, and removing t = malloc(20);.
The first problem to fix is that t in main should have the type T *, not T. You are making a dynamic memory allocation, and seem to want to store that pointer in t, so you would need: T *t;.
The second problem is that you want to manipulate the value of t in main, but are passing it by value to first. Instead, you need to pass a pointer to t into first: first(&t);.
Fixing both of these, you now pass a pointer to a pointer to T (the type of &t) into first and second, so you need to change their signatures to be, respectively, void first(T **t) and void second(T **t).
Applying both changes, as well as making some small style tweaks, we get:
typedef struct T {
int one;
int two;
int three;
int four;
} T;
void second(T **t_ptr) {
*t_ptr = malloc(20);
memcpy(*t_ptr, mydata, 20);
}
void first(T **t_ptr) {
second(t_ptr);
}
int main() {
T *t;
first(&t);
}
Another thing that's missing, and needs to be added, is checking for the success of malloc, but I haven't added that to the above code.
Also, what you've shown in the question shouldn't compile; you're passing a struct to a function that accepts a pointer.
Your problems are common to new C developers. And actually you have two of them.
The first problem is that you pass your structure by value.
The first function is declared to receive a pointer to T but you pass t and not &t (which is the address of t - and this is what you want when a function accepts a pointer).
However there is still another problem so that even if you change your code as suggested above it will still not work correctly. second allocates memory using malloc. The function receives T as a pointer T *t. You assign the output of malloc to t in effect overwriting what t points to (and if t was previously allocated you will leak memory here).
Bellow you can see a correct code for what you want.
typedef struct _t {
int one;
int two;
int three;
int four;
} T;
/* Make sure we have some data to initialize */
T mydata = {0};
/*
We take a pointer to a pointer and change what the external pointer points to. */
In our example when this function is called *ppt is NULL
and t is a pointer to t in main()
*/
void second(T **ppt) {
/*
We never calculate the size of structures by hand. It can change depending on
OS and architecture. Best let the compiler do the work.
*/
*ppt = (T*)malloc(sizeof(T));
memcpy(*ppt, &mydata, sizeof(T));
}
void first(T **ppt) {
/* Make sure we don't leave dangling pointers. */
if (NULL != *ppt)
free(*ppt);
second(ppt);
}
int main() {
T *t = NULL; /* A pointer to our data */
/*
We pass a pointer to our pointer so that the function can change the value it
holds
*/
first(&t);
/* Always do an explicit return if the type of the function is not void */
return 0;
}
How to understand what is going on:
First we declare t as a pointer to a memory holding a type T and we make sure we initialize the pointer to point to NULL (which is a convention meaning that the pointer is not initialized).
We have a function that will allocate the memory for us using malloc. malloc allocates memory from the heap and returns the address of that memory. (In reality a pointer is just a variable holding an address in memory). We want to place that address in t declared in main(). To do so we need to pass to the allocating function the address of t so it can be modified. To do this we use the address of operator - &. This is why we call the function like this first(&t).
Our allocating function accepts a pointer to a pointer. This is because we want to change the address t points to. So we declared the parameter as T **ppt. It holds the address of the pointer *t in main. In the function we dereference the pointer to the pointer to get the original pointer we want to assign the address malloc returns.

c char pointers memory and global variables

The pointer to my global variable is turning to crud after freeing the local resource that I use to set the value in c.
this is the .c class
char* resource_directory;
void getResourcePath()
{
char *basePath = SDL_GetBasePath();
char* resource_dir = (char*)malloc(37 * sizeof(char));
for(int i = 0; i < 25; i++)
{
resource_dir[i] = basePath[i];
}
strcat(resource_dir, "resources/");
resource_dir[36] = '\0';
*resource_directory = *resource_dir;
free(basePath);
// free(resource_dir); <--- If I free here the value goes to crud
}
(this line below should say the value at resresource_directorydir equals the value at resource_dir) right?
*resource_directory = *resource_dir;
so the value at the address of the first pointer should get the value of the address at the 2nd but after trying to free the resource towards the end of the function.
even doing a print statement of the addresses show that they have different addresses.
SDL_Log("%d, %d", &resource_directory, &resource_dir);
example output : 245387384, 1361037488
I get the feeling that I am making a silly mistake here but I don't know what it is.
This line,
*resource_directory = *resource_dir;
is assigning the first value resource_dir points to, to the uninitialized pointer resource_directory, it's equivalent to
resource_directory[0] = resource_dir[0];
which is clearly not what you want.
You need to assign the pointer
resource_directory = resource_dir;
but you shouldn't use a global variable for that, and specially
Don't malloc() it, you have to free() everything you malloc() and global variables make it hard.
Don't use malloc() for fixed size objects, instead declare it as an array with the appropriate size, like this
char resource_directory[37];
Copy strings with strcpy() instead of writing a loop your self
for(int i = 0; i < 25; i++)
{
resource_dir[i] = basePath[i];
}
woule be
strcpy(resource_dir, basePath);
One thing you should notice when using a global variable like this is that if you call getResourcesPath() more than once, you are going to leak resources, if you must use global variables to carry values that need to live as long as the whole program lives, try to make their initialization static, and you can completely avoid using global variables for that, because everything that you declare and initialized in the stack frame of main() will hafe the same lifetime as the program, so you can pass it as parameters to any function that requires them from within main(), if you have many of these variables, create a struct to hold them, and pass the struct across the functions that need these resources, this is a very common technique in fact.
This statements
SDL_Log("%d, %d", &resource_directory, &resource_dir);
outputs as integer values the addresses of global variables resource_directory and local variable resource_dir. Of course their addresses are different.
As for this statement
*resource_directory = *resource_dir;
then it stores the first character of the string pointed to by resource_dir at the address that is stored in pointer resource_directory. However initially resource_directory was initialized by zero as an object with the static storage duration. So the program has undefined behaviour.
I think you mean the following
resource_directory = resource_dir;
That is you wanted that resource_directory would point to the string built in the function.
And there is no sense to use statement
free(resource_dir); <--- If I free here the value goes to crud
necause in this case statement
resource_directory = resource_dir;
also does not have sense.
If resource_directory need to point to the built in the function string then you shall not destroy it.
Take into account that using magic numbers 37 and 25 makes the program unclear and error-prone.
A pointer is a variable that contains a numeric value which happens to be the address of a memory location. For example, a NULL pointer is a variable containing the value 0. Assigning the notion of "isa pointer" to is a way of notifying the compiler of your intended use: that is, you cannot use pointer syntax on non-pointer variables. But until you do use pointer syntax, they more or less behave like normal variables.
int i = 0;
int* p = &i;
int j;
int* q;
j = i; // j has the same value as i
q = p; // q has the same value as p
At the end of the above code, p and q point to the same address. We only use the * syntax when we want to dereference a pointer:
q = p;
*q = *p; // copies the `int` pointed to by `p` to
// the `int` memory location pointed to by `q`,
// which is the same location.
Note that it is possible to nest pointers:
int** pp = &p;
p is int*, so &p is int**.
pp is a numeric value, it is the address of a memory location that contains an int*. *pp means fetch the value at the memory location contained in pp which will retrieve a second numeric value - the value that is in p, which is itself an int* and thus a second address. **pp will retrieve us the integer to which p points.
Your assignment
*resource_directory = *resource_dir;
copies the pointed-to-values, not the addresses.
Since you have tagged your question as C++ I'm going to conclude by offering this alternative implementation:
std::string resource_dir;
void getResourcePath()
{
char *basePath = SDL_GetBasePath();
resource_dir = base_path;
resource_dir += "resources/";
free(basePath);
}
If you need the c-string value of resource_dir subsequently, use resource_dir.c_str().
Alternatively, if you require a C implementation:
char* resource_dir;
void getResourcePath()
{
const char subPath[] = "resources/";
size_t length;
char *basePath = SDL_GetBasePath();
if (resource_dir)
free(resource_dir);
length = strlen(basePath) + sizeof(subPath);
resource_dir = (char*)malloc(length);
snprintf(resource_dir, length, "%s%s", basePath, subPath);
free(basePath);
}

Relation between pointers and the memory in the heap

I am a new C developer. I have been programming in Java for 3 years now.
I noticed the manual memory allocation I have to do in C.
However, it is still ambiguous to me when it comes to pointers and memory allocation.
I will say what I understand and please if anyone has any comment on what I have to say, please correct me.
So let's say I have:
int *a;
So what this does is creates a pointer called a that points to an integer value.
int *a = address;
If I print address, I will get the address.
Let's say I want the value, I do what we call dereferencing and
int *a = *value;
If I print value in this case, I would get the actual number stored in memory.
I noticed in the ebook I am using, that sometimes, we allocate memory in the heap.
Is it always the case? Everytime I need to use a pointer for a string for example using char*, I have to use alloc() and sizeof() to respectively allocate memory according to the size of the intended type?
OK. Pointers for the Java guy.
When you declare
int *a;
it is the same as in Java doing:
Integer a;
Java does not have pointers, but all objects are held by references. So,
Integer a = new Integer(3);
is the same as:
int *a = malloc(sizeof(int));
in C.
Now, Java does not have an & operator, and you cannot do pointer arithmetic, but references really are roughly the same otherwise.
To answer your questions:
does it always have to come from the heap?
No. In C you can point a pointer at something that is already allocated on the stack (or anywhere else in RAM, such as a DMA register for doing hardware interactions):
void f() {
int i;
int *a = &i;
*a = 3; // same as i = 3
a = (int*)0x12340000; // some address in memory, possibly screen RAM?
*a = 0xffffffff; // possibly set some colors on the screen
}
Do I have to use malloc and sizeof every time to allocate space?
If you do use malloc, then yes, you have to specify how much space you want. But you can just as easily ask the compiler to allocate the space in static data space:
void f() {
char *p = "hello";
....
}
In this case, the literal string typically becomes part of the compiled program, and is placed in a statically allocated spot at program startup by the OS.
int *a = *value;
This is incorrect unless value is declared to be an int **:
int **value;
Below is a sequence of using an int pointer with appropriate comments:
int num1; // Declare an int
int num2; // Declare a different int
int *pNum = &num1; // Declare an int pointer and set its value to the address of num1
*pNum = 6; // Set the value of num1
pNum = &num2; // Change value of int pointer to the address of num2
*pNum = 10; // Set the value of num2

The logic behind pass by pointer to pointer in C

I learned from this page: FAQ that, if you want to initialize a pointer inside a function, then you should pass a pointer to pointer, i.e, **p as foo1()
void foo1(int **p) {
*p = malloc(100*sizeof(int)); // caller can get the memory
}
void foo2(int *p) {
p = malloc(100*sizeof(int)); // caller cannot get the memory
}
However, a pointer means its value is the address it points to. Where does the memory allocated in foo2() go after leaving its scope?
I still can't figure out the different behavior between passing pointer to value and pointer to pointer? I search through SO but only found the solution or short description. Could anyone help in more detail?
The memory allocated in foo2 is lost. This creates a memory leak because you have no idea where to find and use the allocated memory after foo2 returns.
Consider:
int *mymemory = NULL;
foo2(mymemory);
//mymemory is still NULL here. Memory has been allocated,
//but you don't know at which address
//in particular, you will never be able to free() it
versus:
int *mymemory = NULL;
foo1(&mymemory);
//mymemory is now the address of the memory
//allocated by the function
dostuffwith(mymemory);
free(mymemory);
Maybe it helps if we start with only one level of indirection.
consider this:
void foo1(int *p) {
^^
//this p is local to the foo1 function
//p contains the address of an int
*p = 12;
//now we dereference the pointer, so we set what p points to , to 12
}
void func(void) {
int x;
^^
//here is the x
foo1(&x);
^^
//now we find the location (address of) x, we copy that address
//into the arguments for foo1()
//foo1 sets our x int to 12
}
Let's add one more indiretion:
void foo1(int **p) {
^^
//this p is local to the foo1 function
//p contains the address of a pointer to an int
*p = NULL;
//now we dereferenced the pointer, so we get an int*. We just
//set it to NULL
}
void func(void) {
int *x;
^^
//here is the x.
foo1(&x);
^^
///now we find the location (address of) x, we copy that address
//into the arguments for foo1()
//foo1() sets the x pointer to NULL.
}
In both cases we are able to manipulate the x variable inside func1(), since the location(address of)
the x variable is passed into func1().
In the last case, we did *p = NULL;. Which would make x == NULL. We could have set it
to something that malloc() returned: *p = malloc(100)
But if we alter the first case:
void foo1(int *p) {
^^
//this p is local to the foo1 function
//p contains the address of an int
p = NULL;
//now we just set the local `p` variable to NULL.
//the caller will not see that, since `p` is just our own copy
//of pointer.
}
void func(void) {
int x;
^^
//here is the x
foo1(&x);
//foo1 just set its own copy of the pointer we created by doing `&x` to NULL.
//we will not see any changes here
}
We just set p = NULL; in the last case here. If we used malloc instead:
void foo1(int *p) {
^^
p = malloc(100);
//now we just set the local `p` variable to what malloc returns.
//the caller will not see that, since `p` is just our own local copy
//of the pointer.
//When foo1() returns, noone has any way of knowing the location
//of the memory buffer that malloc returned, so this memory is lost (a memory leak)
}
In your second example the memory allocated is leaked - once foo2 ends, there is no variable left that contains the address that was allocated, so it can't be freed.
You could also consider
void foo3 (int bar) {
bar = 8;
}
int main (int argc, char *argv[]) {
int x = 0;
foo3(x);
printf("%d\n", x);
return 0;
}
when foo3 ends, x is still 0 - the change to the contents of bar in foo3 don't affect the outer variable that was passed in. You're doing exactly the same when you pass in a single pointer - you're assigning the address of some memory to it, but then losing that address when the function exits.
To better understand indirection levels in C, it can be instructive to look at how the compiler organizes its memory.
Consider the following example :
void function1 (int var1, int var2) { ... }
In this case, function1 will receive 2 variables. But how ?
These variables will be put into the call stack memory. This is a linear, LIFO (Last in, First Out) type of allocation strategy.
Before calling function1(), the compiler will put var1 then var2 into the call stack, and increment the position of the call stack ceil. Then it will call function1(). function1() knows it must get 2 arguments, and so it finds them into the call stack.
What happens after function1() finishes ? Well, the call stack is decremented, and all variables into it are simply "disregarded", which is almost the same as "being erased".
So it's pretty clear that whatever you do to these variables during function1() is going to be lost for the calling program. If anything has to remain available to the calling program, it needs to be provided into a memory space that will survive the call stack decrement step.
Note that the logic is the same for any variable inside function1() : it will be unavailable to the calling function after function1() finishes. In essence, any result still stored into function1() memory space is "lost".
There are 2 ways to retrieve a usable result from a function.
The main one is to save the result of the function into a variable of the calling program/function. Consider this example :
int* foo3(size_t n) { return (int*) malloc(n); }
void callerFunction()
{
int* p;
p = foo3(100); // p is still available after foo3 exits
}
The second, more complex, one is to provide as an argument a pointer to a structure which exists into the calling memory space.
Consider this example :
typedef struct { int* p; } myStruct;
void foo4(myStruct* s) { s->p = (int*) malloc(100); }
void callerFunction()
{
myStruct s;
foo4(&s); //p is now available, inside s
}
It is more complex to read, but also more powerful. In this example, myStruct contains a single pointer, but the structure could be a lot more complex. This open the perspective to offer myriad of variables as the result of a function, instead of being limited to basic types, as for the previous example with foo3().
So what happens when you know that your structure is in fact a simple basic type ? Well, you can just provide a pointer to it. And, by the way, pointer is itself a basic type. So if you want to get the result of a modified pointer, you can provide as an argument, a pointer to a pointer. And there we find foo1().
void foo1(int **p) {
*p = (int *) malloc(100); // caller can get the memory
}
The problem with foo2 is that the p which is passed in is only modified inside the foo2 function. This is the same as :
void bar(int x)
{
x = 42;
}
...
int a = 7;
bar(a);
...
In the above code, a doesn't change because of the call to bar. Instead, a copy of a is passed to bar, and the copy is modified in bar.
The exact same thing happens in foo2. The memory is allocated, stored in p, which is a copy of the pointer passed in. When the code returns, the original pointer retains its original value.
By passing the address of a pointer (&ptr) to foo1, we can modify the ORIGINAL pointer, and thus pass the address of the allocation back to the caller of foo1.
Of course, when there is no reference back to the originally allocated memory, as is the case after a call to foo2, it is called a memory leak - generally considered a bad thing.
Passing a pointer to value: A copy of the pointer(i.e. address of the value) is made in the function(on the stack frame). This allows you to modify the value.
Passing a pointer to a pointer: A copy of the pointer to a pointer(i.e. address of the pointer which in turn points to the value) is made in the function(on the stack frame). This allows you to modify the value as well as the pointer to this value.
The memory allocated using malloc, calloc, realloc and new resided on the heap which means that it exists even after a function returns(stack frame destroyed).
void foo2(int *p) {
p = (int *) malloc(100); // caller cannot get the memory
}
However, since the pointer p is lost after the function is returned, this memory cannot be accessed and will result in a leak.
As behaviour of all arguments is the same as local variables (they are passed by value), you can not modify pointer passed by value.
So in foo2() you allocate memory, but you can not use it outside the function, as you actually modify local variable.
The foo() function actually modifies the value pointed by **p, so pointer passed to function will be updated.

pointer and which is pointed by the pointer

Update : Sorry, just a big mistake. It is meaningless to write int *a = 3; But please just think the analogy to the case like TCHAR *a = TEXT("text"); (I edited my question, so some answers and comments are strange, since they are for my original question which is not suitable)
In main function, suppose I have a pointer TCHAR *a = TEXT("text"); Then it excutes the following code:
int i;
for (i = 0; i < 1000; i++) {
a = test(i);
}
with the function TCHAR* test(int par) defined by:
TCHAR* test(int par)
{
TCHAR *b = TEXT("aaa");
return b;
}
My question is, after executing the above code, but before the program ends, in the memory:
1. the pointer `a` remains?
2. The 1000 pointers `b` are deleted each time the function test(...) exits ?
3. But there are still 1000 memory blocks there?
In fact, my question is motivated from the following code, which shows a tooltip when mouse is over a tab item in a tab control with the style TCS_TOOLTIPS:
case WM_NOTIFY
if (lpnmhdr->code == TTN_GETDISPINFO) {
LPNMTTDISPINFO lpnmtdi;
lpnmtdi = (LPNMTTDISPINFO)lParam;
int tabIndex = (int) wParam; // wParam is the index of the tab item.
lpnmtdi->lpszText = SetTabToolTipText(panel->gWin.At(tabIndex));
break;
}
I am thinking if the memory usage increases each time it calls
SetTabToolTipText(panel->gWin.At(tabIndex)), which manipulates with TCHAR and TCHAR* and return a value of type LPTSTR.
Yes, the pointer a remains till we return from the main function
The variable b (a 4-byte pointer) is automatic. It is created each time we call test function. Once we return from it, the variable disappears (the pointer). Please note, the value to which b points isn't affected.
No. In most of the cases, I think, there will be only one block allocated during compilation time (most likely in the read-only memory) and the function will be returning the same pointer on every invocation.
If SetTabToolTipText allocates a string inside using some memory management facilities new/malloc or some os-specific, you should do an additional cleanup. Otherwise there'll be a memory leak.
If nothing like this happens inside (it's not mentioned in the documentation or comments etc), it's most likely returning the pointer to some internal buffer which you typically use as readonly. In this case, there should be no concerns about a memory consumption increase.
You dont allocate any memory so you don't have to worry about memory being freed. When your vaiables go out of scope they will be freed automatically. In this function
int test(int par)
{
int *b = par;
}
you don't have a return value even though the function says that is will return an int, so you should probably do so as in this line
for (i = 0; i < 1000; i++) {
a = test(i);
}
you assign to a the value that is returned by test(). Also
int* a = 3;
int* b = par;
are asking for trouble. You are assigning integer values to a pointer variable. You should probably rethink your above code.
Pointer should contain adress... so int* a = 3 is something meaningless... And in function you don't allocate memory for int (only for par variable, which then destroy when the function ends), you allocate memory for storing adress in int* b, this memory also free when the funciton ends.

Resources