Dynamically allocating in main() VS in a funtion - c

int foo(int *p){
p = malloc(sizeof(int));
*p = 20;
}
int main(){
int a;
int *x;
x = &a;
foo(x);
printf("%d \n", a);
return 0;
}
So I'm trying to point at a and then set the value of what x is pointing to 20. However whenever I allocate the pointer in the function I get a random number being printed. Do you know why this happens compared to allocating it in main()?
Thanks

You don't want to allocate in the foo function at all. This is like doing:
void foo(int p) {
p = 2;
printf("%d\n", p);
}
int main() {
int a=1;
foo(a);
return 0;
}
And asking why it didn't print 1. The answer is, you're writing over the pointer to a, so you no longer have a pointer to a when you do *p = 20;.

So I'm trying to point at a and then set the value of what x is pointing to 20
This doesn't make sense given the context of your question. You are pointing x at a, and if you want to change the value of a, then why are you dynamically allocating anything at all? a is already automatically allocated in main(). If you want to dynamically allocate something, what you you need a for at all?
To change the value of a, just pass a pointer to it and forget about malloc():
void foo(int * p)
{
*p = 20;
}
int main(void)
{
int a;
foo(&a);
printf("%d\n", a);
return 0;
}
If you want to dynamically allocate, forget about a, and don't modify it through a passed pointer - return the pointer:
int * foo(void)
{
int * p = malloc(sizeof *p);
if ( !p ) {
perror("could not allocate memory");
exit(EXIT_FAILURE);
}
*p = 20;
return p
}
int main(void)
{
int * x = foo();
printf("%d\n", *x);
free(x);
return 0;
}

Related

Problem with storing value in pointer address

I managed to put the value in the pointer while in the function, However when i come back to the main i just dont get the values. Where am i wrong? sending parameters wrong? wrong allocation? Here's the code:
bool wc(int* nlines, int* nwords, int* nchars)
{
int lines=5,chars=6,words=7;
nchars = (int *) malloc(chars*sizeof(int));
*nchars = chars;
nlines = (int *) malloc(lines*sizeof(int));
*nlines = lines;
nwords = (int *) malloc(words*sizeof(int));
*nwords = words;
}
int main() {
int* chars; int* words; int* lines;
int res = wc(&lines,&words,&chars);
printf("%d %d %d\n",chars,lines,words);
return 0;
}
If all you want to do is be able to set 3 int values inside a function then this is how I would so it.
#include <stdio.h>
#include <stdbool.h>
bool wc(int* nlines, int* nwords, int* nchars)
{
int lines=5,chars=6,words=7;
*nchars = chars;
*nlines = lines;
*nwords = words;
return true;
}
int main() {
int lines = 0;
int words = 0;
int chars = 0;
int res = wc(&lines,&words,&chars);
printf("%d %d %d\n",chars,lines,words);
return 0;
}
If for some reason you must use pointers as shown in your example then this will do what you want.
#include <stdio.h>
#include <stdbool.h>
bool wc(int** nlines, int** nwords, int** nchars)
{
int lines=5,chars=6,words=7;
*nchars = malloc(sizeof(int));
**nchars = chars;
*nlines = malloc(sizeof(int));
**nlines = lines;
*nwords = malloc(sizeof(int));
**nwords = words;
return true;
}
int main() {
int* chars; int* words; int* lines;
int res = wc(&lines,&words,&chars);
printf("%d %d %d\n",*chars,*lines,*words);
free(chars);
free(words);
free(lines);
return 0;
}
As you can see this just means you need to add a bunch more * all over the place.
In C function input variables are passed by value, not reference. So when you assign them locally, the value in the caller scope is unaffected. E.g.
void foo(int a) {
a = 5;
}
int main() {
int b = 3;
foo(b);
// here, b is still 3
}
This is exactly what you are doing in your example, though your variables are not int, but int*.
If your input variable is a pointer though, you can change the memory that the variable points to, and this will obviously reflect in the calling scope. E.g.
void foo(int *a) {
*a = 5;
}
int main() {
int b = 3;
foo(&b);
// here, b is 5
}
In your case, you want to allocate pointers, so you want your function signature to be a pointer to a pointer. E.g.
void foo(int **a) {
*a = malloc(sizeof(int));
}
int main() {
int* b = NULL;
foo(&b);
// here, b is allocated to a valid heap area
free(b);
}

how do I dereference a pointer which I got from a function in c?

#include <stdio.h>
#include <stdlib.h>
int* CreateArray(int length){
int arr[length];
int i;
for(i=0; i < length; ++i){
arr[i] = -25;
int* ptr = &arr[i];
printf("%p \n",ptr);
printf("%d \n",*ptr);
}
printf("%d \n",arr[0]);
int* location = &arr;
return location;
}
void main()
{
int* arr = CreateArray(10);
printf("pointer here is %p \n",arr);
int num = *arr;
printf("%d",num);
}
when i run the program i want num to be equal to arr[0] which was declared in the function but it doesn't do that for some reason
The array arr is local to the function CreateArray and not marked as static, so it will deleted on returning from the function and cannot be used after that.
To avoid this, you should allocate arrays dynamically.
Also note that &arr is int(*)[length], so it is not good to assign that to a variable of type int*.
int* CreateArray(int length){
int *arr = malloc(sizeof(*arr) * length); /* allocate dynamically */
if (arr == NULL) exit(1); /* check if allocation succeeded */
int i;
for(i=0; i < length; ++i){
arr[i] = -25;
int* ptr = &arr[i];
printf("%p \n",(void*)ptr); /* void* should be passed for %p */
printf("%d \n",*ptr);
}
printf("%d \n",arr[0]);
int* location = arr; /* assign arr, not &arr */
return location;
}
Your function is returning a pointer created inside the function, and it will be deinitialized when the function is popped from the stack. This is called dangling pointer.
If you want to return a pointer, you have to create it on the heap:
int* arr = malloc(sizeof(*arr) * length);;
But pay attention, now you have to manage the garbage!

C Passing and Reassinging Pointers in Functions

Here's the function in question. Why does x not change, despite having ptr reference it's memory address? Similarly why doesn't y change?
#include <stdio.h>
int func (int a, int *b)
{
int *ptr = &a;
*ptr += 5;
ptr = b;
*ptr -= 3;
return a;
}
int main ()
{
int x = 2;
int y = 8;
int ret = func (x, &y);
printf ("x: %d\n", x);
printf ("y: %d\n", y);
printf ("ret: %d\n", ret);
return 0;
}
Edit: yes y does change. Sorry.
int func (int a, int *b)
'a' is passed by value. Inside func() a has its own memory allocated, so anything you do to it does not affect the variable that was passed in. 'b' is a pointer to an int so changing the data at that address is still visible outside the scope of func(). Hence, x doesn't change, but y does.

C Pointer Not Being Set Equal to Another

void s(int* a, int* b) {
a=b;
}
int main(int argc, char* argv[]) {
int* a = malloc(sizeof(int));
int* b = malloc(sizeof(int));
int c = 10;
int d = 5
a = &c;
b = &d;
printf("%d %d\n",*a,*b);
s(a,b);
printf("%d %d\n",*a,*b);
}
I am so very confused. This is very simple code. I thought that this would result in a and b pointing to the same value. When i do a=b inside of the main function everything works as expected. When I use gdb it even shows that they point to the same place in memory and the function is not being optimized away!!! So what is happening?
Is the function creating its own local copy? Why don't these point to the same variable please help.
You want to change the pointers values. Pointers are passed by value, so you need a pointer to the pointer to change its value:
#include <stdio.h>
void s(int** foo, int** bar)
{
*foo = *bar;
}
int main(void)
{
int c = 10;
int d = 5;
int *a = &c;
int *b = &d;
printf("%d %d\n", *a, *b); // 10 5
s(&a, &b);
printf("%d %d\n", *a, *b); // 5 5 a points at d as well
}
With your version you only changed the parameters which are copies of the values passed to the function.
To help you better understand, consider this:
#include <stdio.h>
void value(int foo, int bar)
{
foo = bar; // changing local copies
}
void pointer(int *foo, int *bar)
{
*foo = *bar; // changing the value foo points to to the value bar points to
}
int main(void)
{
int a = 5;
int b = 7;
value(a, b);
printf("%d, %d\n", a, b); // 5, 7
pointer(&a, &b);
printf("%d, %d\n", a, b); // 7, 7
}
We did that with the type int. Now lets just replace int with int*:
#include <stdio.h>
void value(int *foo, int *bar)
{
foo = bar; // changing local copies
}
void pointer(int **foo, int **bar)
{
*foo = *bar; // changing the value foo points to to the value bar points to
}
int main(void)
{
int x = 5;
int y = 7;
int *a = &x;
int *b = &y;
value(a, b);
printf("%d, %d\n", *a, *b); // 5, 7
pointer(&a, &b);
printf("%d, %d\n", *a, *b); // 7, 7 now both point at y
}
So you see, it's the same concept both times. In the first example the values pointed to are ints and their values are numbers, in the second example the values pointed to are int*s and their values are pointer values (<~ standard terminology, "addresses"). But the mechanism is the same
You program is almost correct but you need to pass the address of the variables in the function as you using call by refrence and in the function take pointer to pointers.

Pointers and Address in C

I write a C program. I have 2 pointers *a and *b. Now, I impose *a = 20 and *b = 10. After that I impose a = b in subroutine but the value seem doesn't change. I expect that *a = 10 and *b = 10. Please help me find a solution for this. Thank you.
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
void Copy(int *a1, int *a2)
{
a1 = a2;
}
void Test()
{
// a = 20
int *a = (int *)malloc(sizeof(int));
*a = 20;
// b = 10
int *b = (int *)malloc(sizeof(int));
*b = 10;
Copy(a, b); // a = b
printf("\na = %d", *a);
printf("\nb = %d", *b);
}
int main(int argc, char *argv[]){
Test();
fflush(stdin);
printf("\nPress any key to continue");
getchar();
return 0;
}
Function arguments are passed by value. So inside the function Copy you are modifying a copy of the pointer not the original pointer you had in the Test function. So when you leave the Copy function the pointers outside are not modified.
Change the Copy to receive a int **, so you can change inside the value of pointers
void Copy(int **a1, int **a2)
{
*a1 = *a2;
}
And call the function in this way:
void Test() {
...
Copy (&a, &b);
...
}
If you want to assign the values, such that after the call of Copy *a == *b holds, then you'd have to change your function as follows:
void Copy(int *a1, int *a2)
{
*a1 = *a2;
}
If you want to assign the pointers, such that after the call of Copy a==b holds, then you have to pass a pointer to the pointers:
void Copy(int **a1, int **a2)
{
*a1 = *a2;
}
void Test() {
...
Copy (&a, &b);
...
}
Note that a==b also implies that *a == *b.

Resources