C pointer lost after multiple assignments - c

I am new to C programming and having some issues with the pointers in the following code. I am using the C89 standard.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char * b(char *p) {
char *z;
z = p;
printf("b(): %s\n", z);
return z;
}
void a(char *p, char *q) {
q = b(p);
printf("a(): %s\n", q);
}
void main(void) {
char *p = (char *) malloc(15);
char *q;
strcpy(p, "This is a test");
a(p,q);
printf("main(): %s\n", q);
free(p);
}
For some reason, my printf function is printing nothing in the main() function. The printf calls in both of the functions a() and b() are working. I am not sure why my pointer "q" is lost in the main function. I even tried allocation dynamic memory to "q" in main() function but still no results.

q in main() is uninitialized. You probably assume that q is changed after a(p,q), but as that pointer is passed by value (as everything in C), after returning from a, any changes done to q are discarded (they were local to a)
To solve this, while preserving most of your function signatures, you would have to add another level of pointers
In following code, p and q in a are local to a, but you are not directly changing any of them, insted, you are modifying value, that is pointed at by q (that value is of type *char, so another ponter, easy to get lost)
void a(char *p, char **q) {
*q = b(p);
printf("a(): %s\n", q);
}
void main(void) {
...
a(p,&q);
printf("main(): %s\n", *q);
....
}
Or simply return that pointer, and assign to q in main (as you have done in b)
To better understand why this is happening, consider this simpler example:
void foo(int a) {
print("value is %d\n", a);
a = 42; // modifies only a local copy of passed parameter a
print("modified value is %d\n", a);
}
int main() {
int a = 0
printf("initial value is %d\n", a);
foo(a);
printf("value after returning is (still) %d\n, a");
}

Related

free(): double free detected in tcache 2 - realloc - binary tree - c [duplicate]

If I've declared a pointer p as int *p; in main module, I can change the address contained by p by assigning p = &a; where a is another integer variable already declared.
I now want to change the address by using a function as:
void change_adrs(int*q)
{
int *newad;
q = newad;
}
If I call this function from main module
int main()
{
int *p;
int a = 0;
p = &a; // this changes the address contained by pointer p
printf("The address is %u\n", p);
change_adrs(p);
printf("The address is %u\n", p); // but this doesn't change the address
return 0;
}
the address content is unchanged. What's wrong with using a function for same task?
In C, functions arguments are passed by value. Thus a copy is made of your argument and the change is made to that copy, not the actual pointer object that you are expecting to see modified. You will need to change your function to accept a pointer-to-pointer argument and make the change to the dereferenced argument if you want to do this.
For example
void foo(int** p) {
*p = NULL; /* set pointer to null */
}
void foo2(int* p) {
p = NULL; /* makes copy of p and copy is set to null*/
}
int main() {
int* k;
foo2(k); /* k unchanged */
foo(&k); /* NOW k == NULL */
}
If you have the luxury of using C++ an alternative way would be to change the function to accept a reference to a pointer.
In C, variables are passed by value - a copy of the pointer is passed to the function. Use another pointer to the pointer instead:
void change(int **p, int *someOtherAddress)
{
*p = someOtherAddress;
}
int a = 1, b = 2;
int *p = &a;
printf("*p = %d\n", *p);
change(&p, &b);
printf("*p = %d\n", *p);
This prints
*p = 1
*p = 2
If you want to alter the content of a variable in a function in C, pointer is a kinda variable as well, you have to pass it by pointer or indirect reference by using always & address and * dereference operators. I mean * operator is always used and preceded when changing the value of a variable.
#include <stdio.h>
#include <stdlib.h>
void changeIntVal(int *x) {
*x = 5;
}
void changePointerAddr(int **q) {
int *newad;
*q = newad;
}
void changePPAddr(int ***q) {
int **dummy;
*q = dummy;
}
int main() {
int *p;
int **pp;
int *tempForPP;
int a = 0;
printf("\n The address pointing by p -> %p, pp -> %p, value of a -> %d ", p, pp, a);
p = &a;
pp = &tempForPP;
printf("\n The address pointing by p -> %p, pp -> %p, value of a -> %d ", p, pp, a);
changeIntVal(&a); // ----
// |---
changePointerAddr(&p); // ---- |----> parts of what I mean
// |---
changePPAddr(&pp); // ----
printf("\n The address pointing by p -> %p, pp -> %p, value of a -> %d ", p, pp, a);
return 0;
}
For a primitive data type such as an int, the double pointers are not necessary. You can write directly into the address where the int is stored, treating its address as a pointer in the function being called. This is unlike a char array ("string") where the size of what is pointed to is variable and you must therefore use another level of indirection when changing it from within a called function. Try this:
void foo(int *oldVal)
{
int newVal = 99; // or whatever you want
*oldVal = newVal;
}
int main(int argc, char *argv[])
{
int someVal = 0;
foo(&someVal); // we send its address to foo()
printf("someVal is now %d.\n", someVal);
return EXIT_SUCCESS;
}
This won't change the actual value of p because the q in function is local to that and change in that function will not reflect in main so pass the address of p instead of passing p by value
Use this syntax below
void change_adrs(int **q)
{
int * otheraddess;
*q = otheraddress;
}
and call like this change_adrs(&p);
Or, you have other way around:
change the return type of function and catch the returned address.
int* change_adrs(int *q)
{
int * otheraddess;
q = otheraddress;
return q;
}
int main()
{
p = change_adrs(p);
return 0;
}

How to resize array of pointers without getting memory reallocation errors in C? [duplicate]

If I've declared a pointer p as int *p; in main module, I can change the address contained by p by assigning p = &a; where a is another integer variable already declared.
I now want to change the address by using a function as:
void change_adrs(int*q)
{
int *newad;
q = newad;
}
If I call this function from main module
int main()
{
int *p;
int a = 0;
p = &a; // this changes the address contained by pointer p
printf("The address is %u\n", p);
change_adrs(p);
printf("The address is %u\n", p); // but this doesn't change the address
return 0;
}
the address content is unchanged. What's wrong with using a function for same task?
In C, functions arguments are passed by value. Thus a copy is made of your argument and the change is made to that copy, not the actual pointer object that you are expecting to see modified. You will need to change your function to accept a pointer-to-pointer argument and make the change to the dereferenced argument if you want to do this.
For example
void foo(int** p) {
*p = NULL; /* set pointer to null */
}
void foo2(int* p) {
p = NULL; /* makes copy of p and copy is set to null*/
}
int main() {
int* k;
foo2(k); /* k unchanged */
foo(&k); /* NOW k == NULL */
}
If you have the luxury of using C++ an alternative way would be to change the function to accept a reference to a pointer.
In C, variables are passed by value - a copy of the pointer is passed to the function. Use another pointer to the pointer instead:
void change(int **p, int *someOtherAddress)
{
*p = someOtherAddress;
}
int a = 1, b = 2;
int *p = &a;
printf("*p = %d\n", *p);
change(&p, &b);
printf("*p = %d\n", *p);
This prints
*p = 1
*p = 2
If you want to alter the content of a variable in a function in C, pointer is a kinda variable as well, you have to pass it by pointer or indirect reference by using always & address and * dereference operators. I mean * operator is always used and preceded when changing the value of a variable.
#include <stdio.h>
#include <stdlib.h>
void changeIntVal(int *x) {
*x = 5;
}
void changePointerAddr(int **q) {
int *newad;
*q = newad;
}
void changePPAddr(int ***q) {
int **dummy;
*q = dummy;
}
int main() {
int *p;
int **pp;
int *tempForPP;
int a = 0;
printf("\n The address pointing by p -> %p, pp -> %p, value of a -> %d ", p, pp, a);
p = &a;
pp = &tempForPP;
printf("\n The address pointing by p -> %p, pp -> %p, value of a -> %d ", p, pp, a);
changeIntVal(&a); // ----
// |---
changePointerAddr(&p); // ---- |----> parts of what I mean
// |---
changePPAddr(&pp); // ----
printf("\n The address pointing by p -> %p, pp -> %p, value of a -> %d ", p, pp, a);
return 0;
}
For a primitive data type such as an int, the double pointers are not necessary. You can write directly into the address where the int is stored, treating its address as a pointer in the function being called. This is unlike a char array ("string") where the size of what is pointed to is variable and you must therefore use another level of indirection when changing it from within a called function. Try this:
void foo(int *oldVal)
{
int newVal = 99; // or whatever you want
*oldVal = newVal;
}
int main(int argc, char *argv[])
{
int someVal = 0;
foo(&someVal); // we send its address to foo()
printf("someVal is now %d.\n", someVal);
return EXIT_SUCCESS;
}
This won't change the actual value of p because the q in function is local to that and change in that function will not reflect in main so pass the address of p instead of passing p by value
Use this syntax below
void change_adrs(int **q)
{
int * otheraddess;
*q = otheraddress;
}
and call like this change_adrs(&p);
Or, you have other way around:
change the return type of function and catch the returned address.
int* change_adrs(int *q)
{
int * otheraddess;
q = otheraddress;
return q;
}
int main()
{
p = change_adrs(p);
return 0;
}

Sorting a stack with another temporary stack in c gives segmentation fault [duplicate]

If I've declared a pointer p as int *p; in main module, I can change the address contained by p by assigning p = &a; where a is another integer variable already declared.
I now want to change the address by using a function as:
void change_adrs(int*q)
{
int *newad;
q = newad;
}
If I call this function from main module
int main()
{
int *p;
int a = 0;
p = &a; // this changes the address contained by pointer p
printf("The address is %u\n", p);
change_adrs(p);
printf("The address is %u\n", p); // but this doesn't change the address
return 0;
}
the address content is unchanged. What's wrong with using a function for same task?
In C, functions arguments are passed by value. Thus a copy is made of your argument and the change is made to that copy, not the actual pointer object that you are expecting to see modified. You will need to change your function to accept a pointer-to-pointer argument and make the change to the dereferenced argument if you want to do this.
For example
void foo(int** p) {
*p = NULL; /* set pointer to null */
}
void foo2(int* p) {
p = NULL; /* makes copy of p and copy is set to null*/
}
int main() {
int* k;
foo2(k); /* k unchanged */
foo(&k); /* NOW k == NULL */
}
If you have the luxury of using C++ an alternative way would be to change the function to accept a reference to a pointer.
In C, variables are passed by value - a copy of the pointer is passed to the function. Use another pointer to the pointer instead:
void change(int **p, int *someOtherAddress)
{
*p = someOtherAddress;
}
int a = 1, b = 2;
int *p = &a;
printf("*p = %d\n", *p);
change(&p, &b);
printf("*p = %d\n", *p);
This prints
*p = 1
*p = 2
If you want to alter the content of a variable in a function in C, pointer is a kinda variable as well, you have to pass it by pointer or indirect reference by using always & address and * dereference operators. I mean * operator is always used and preceded when changing the value of a variable.
#include <stdio.h>
#include <stdlib.h>
void changeIntVal(int *x) {
*x = 5;
}
void changePointerAddr(int **q) {
int *newad;
*q = newad;
}
void changePPAddr(int ***q) {
int **dummy;
*q = dummy;
}
int main() {
int *p;
int **pp;
int *tempForPP;
int a = 0;
printf("\n The address pointing by p -> %p, pp -> %p, value of a -> %d ", p, pp, a);
p = &a;
pp = &tempForPP;
printf("\n The address pointing by p -> %p, pp -> %p, value of a -> %d ", p, pp, a);
changeIntVal(&a); // ----
// |---
changePointerAddr(&p); // ---- |----> parts of what I mean
// |---
changePPAddr(&pp); // ----
printf("\n The address pointing by p -> %p, pp -> %p, value of a -> %d ", p, pp, a);
return 0;
}
For a primitive data type such as an int, the double pointers are not necessary. You can write directly into the address where the int is stored, treating its address as a pointer in the function being called. This is unlike a char array ("string") where the size of what is pointed to is variable and you must therefore use another level of indirection when changing it from within a called function. Try this:
void foo(int *oldVal)
{
int newVal = 99; // or whatever you want
*oldVal = newVal;
}
int main(int argc, char *argv[])
{
int someVal = 0;
foo(&someVal); // we send its address to foo()
printf("someVal is now %d.\n", someVal);
return EXIT_SUCCESS;
}
This won't change the actual value of p because the q in function is local to that and change in that function will not reflect in main so pass the address of p instead of passing p by value
Use this syntax below
void change_adrs(int **q)
{
int * otheraddess;
*q = otheraddress;
}
and call like this change_adrs(&p);
Or, you have other way around:
change the return type of function and catch the returned address.
int* change_adrs(int *q)
{
int * otheraddess;
q = otheraddress;
return q;
}
int main()
{
p = change_adrs(p);
return 0;
}

Returning pointers back to itself

My coding assignments came with it's header file, meaning we need to use the same data types, and not vary anything.
There is a lot of pointers, (mainly a lot of void *). Meaning things are confusing, more than difficult.
we have to do a separate function, just to increment the value referenced by a pointer. But given the nature of program, I don't want to constantly make new pointers.
The code is as follows:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void* intal_create(const char* );
void* intal_increment(void* );
void *intal_create(const char* str)
{
int a;
a=atoi(str);
return &a;
}
void *intal_increment(void *intal)
{
int *a= (int *)intal;//new pointer;
++*a;
//value referenced has been incremented;
*(int *)intal=*a;
return intal;
}
int main()
{
int * x;// void * return a pointer, need a pointert to int to pick it up
char *dummy;
gets(dummy);
x=(int *)intal_create(dummy);
printf("integer return is %d\n",*(int *)x);
printf("address stored is %p\n",(int *)x);
x=(int *)intal_increment(x);
printf("integer return is %d\n",*(int *)x);
printf("address stored is %p\n",(int *)x);
}
I wanted x to be the parameter called, and also for it to store the return value. The printf address is merely for my understanding.
The segmentation faults never end, and from my understanding, I'm just returning a pointer and asking a pointer to stop the return pointer
By incorporating all the comments. Mainly allocating memory to dummy before passing it gets() function and allocating memory in heap for the return pointer of intal_create.These two fixes solve the issue. Have a look at the following code for reference.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void* intal_create(const char* );
void* intal_increment(void* );
void *intal_create(const char* str)
{
int *a = (int *)malloc(sizeof(int));
*a = atoi(str);
return a;
}
void *intal_increment(void *intal)
{
//Here i am not allocating
int *a = (int *)intal;//new pointer;
(*a)++;
return intal;
}
int main()
{
int * x;// void * return a pointer, need a pointert to int to pick it up
char dummy[20] = {0};
fgets(dummy,5,stdin);
x = (int *)intal_create(dummy);
printf("integer return is %d\n",*x);
printf("address stored is %p\n",(void*)x);
x=(int *)intal_increment(x);
printf("integer return is %d\n",*x);
printf("address stored is %p\n",(void *)x);
//Make sure you deallocate the memory allocated in the intal_create function.
free(x);
}

Pointer question

Okay I go through 2 layers of functions fun1 calls func2 calls func3 . I pass a pointer all the way down using basically int *ptr, at the lowest "level" of the call stack I also have another function that dynamically allocates memory for an int array. At the top level (func1 level) I always get null back for the passed pointer. I have traced down to func3 and the allocated memory is being filled with values, but as the call stack unwinds func3 -> func2 suddenly the pointer just goes away (0x0000_0000)? I don't understand at func3 level I basically say ptr = allocate_ptr_array, but from that return it goes to NULL! Even though I didn't free the memory, what in the world is going on? I know my question is confusing. I have watched this happen in the debugger though
The pointer is basically passed by value. You need to pass pointer to pointer (int **p) to get the memory allocated back in outer function.
function1(int *p)
{
p = //allocate memory using malloc
}
function2(int **p)
{
*p = //allocate memory using malloc
}
function3()
{
int *p;
function1(p);
// in this case pointer is passed by value.
//The memory allocated will not be available in p after the function call function1.
int **p;
function2(&p);
//in this case pointer to pointer p has been passed.
// P will have the memory allocated even after
//the function call function1
}
}
To illuminate aJ's (completely correct) answer with some code:
void func1(void)
{
int *int_array;
func2(&int_array);
/* Some stuff using int_array[0] etc */
/* ... */
free(int_array);
}
void func2(int **a)
{
/* ... stuff ... */
func3(a);
/* .... stuff ... */
}
void func3(int **a)
{
(*a) = malloc(N * sizeof **a);
}
Here is a good example for future reference bye other people. It makes sense after implementation and thanks to these guys.
#include <memory.h>
#include <stdlib.h>
#include <stdio.h>
void func3(int **ptr)
{
int i;
(*ptr) = (int *)malloc(25*sizeof(int));
for (i=0; i < 25; i++) (**ptr) = i;
printf("func3: %d\n",ptr);
}
void func2(int **ptr)
{
func3(ptr);
printf("func2: %d\n", ptr);
}
void func1(void)
{
int *ptr;
printf("ptr before: %d\n", ptr);
func2(&ptr);
printf("ptr after: %d\n", ptr);
}
void func4(int **ptr)
{
static int stuff[25];
printf("stuff: %d\n",stuff);
*ptr = stuff;
}
int main(void)
{
int *painter;
func1();
func4(&painter);
printf("painter: %d\n", painter);
return 0;
}

Resources