How to solve pointer errors? - c

I am new to pointers.
For the below program , I get an answer of 255 and not 20. Please suggest how to correct.
Here is the code :
int sum(int *a , int *b);
int main()
{
int *p;
int *q;
*p =10;
*q =10;
int c = sum(p,q);
printf("%d",c);
}
int sum(int *a , int *b)
{
return((*a)+ (*b));
}

There is data, then there are pointers. For simplicity, once you have data, then you can point to it. This is accomplished by using the & operator. To go back to the data from a pointer, use the * operator as you have
Something more like
int sum(int *a , int *b);
int main()
{
int p_data=10;
int q_data=10;
int *p =&p_data;
int *q =&q_data;
int c = sum(p,q);
printf("%d",c);
}
int sum(int *a , int *b)
{
return((*a)+ (*b));
}
EDIT: Also note that pointers can be used to access memory allocated from malloc, or mmap'd, or other means

You need to alloc memory for pointers. This code should work:
#include <stdio.h>
#include <stdlib.h>
int sum(int *a , int *b);
int main()
{
int *p = (int*) malloc(sizeof(int));
int *q = (int*) malloc(sizeof(int));
if (p != NULL && q != NULL)
{
*p =10;
*q =10;
int c = sum(p,q);
printf("%d", c);
free(p);
free(q);
}
else
{
printf("Could not allocate enough memory");
return 1;
}
return 0;
}
int sum(int *a , int *b)
{
return (*a) + (*b);
}
Hope this helps!

A pointer is a variable that holds the address of another variable, and this seems clear to you. But what seems not still very clear is that when you create a pointer the compiler doesn't automagically create also a variable to point to...
In code:
int *p;
int *q;
*p =10;
*q =10;
You are defining p and q as pointers to int, but to which variables of type int they point? They have a garbage inside and can point anywhere, so when assigning 10 to what they point to, in reality, you are spamming somewhere in memory.
Under these conditions when you call sum I would expect more a memory fault than a strange value (255), but everything can happen with bad pointers, even to access an existing memory.
The correct code is:
int sum(int *a , int *b);
int main()
{
int i1, i2; //Allocate 2 int variables
int *p = &i1; //Create pointers and assign them
int *q = &i2; //the address of int vars i1 and i2
*p =10; //Initialize variables pointed by pointers with 10
*q =10;
int c = sum(p,q);
printf("%d",c);
}
int sum(int *a , int *b)
{
return((*a)+ (*b));
}

A pointer needs to be assign the address of some valid memory to point to before it may be dereferenced of the *-operator and gets written some data to where it points to.
You miss those very assignments.
Dereferencing a pointer implies reading out its value. If no value ever had been assigned to a pointer variable, already reading out its value might invoke the infamous Undefined Behaviour, anything can happen after this.
So your result could also have been just the famous 42.
Lesson learned: Never apply any operator to a variable which had not been properly been initialised.

Another approach. I think it may be useless for return function but it can help you about pointers It is passing pointer to the sum function
#include <stdio.h>
int sum(int *a , int *b);
int main()
{
int p = 10;
int q = 10;
int c = sum(&p,&q);
printf("%d",c);
}
int sum(int *a , int *b)
{
return((*a)+ (*b));
}

You're getting 255 is because of random luck. I get 20 when I compile it, but that's also random luck. The technical term is "undefined behavior", and this is undefined because you never initialized your int *p and int *q pointers.
What's inside your pointer variables? You don't know, I don't know, nobody does. Since you never initialized them, their contents are whatever bits were there before initialization. It's like moving into a house and getting whatever junk the previous tenants left for you.
If the contents of the pointers are addresses in memory (and they don't overlap), then the value returned should be 20 (by random luck). But if one of them contains a null address, who knows what you'll get!
If you want to get 20 reliably, you need to allocate memory:
In C++:
int * p = new int;
int * q = new int;
In C:
int * p = (int*)malloc(sizeof(int))
int * q = (int*)malloc(sizeof(int))

Related

C Segmentation fault after adding a printf function. Works fine after commenting out

I get segmentation fault after executing this part of code.If i comment the first printf out,it works fine.Why does this happen?
#include <stdio.h>
int Func (int *a){
printf("%d\n",56 );
printf("a is %d\n",*a );
return 3;
}
int main(){
int N, i, Planet, *a,junk;
junk=scanf("%d", &N );
*a = N;
Planet = Func(a);
printf("%d\n", Planet);
return 0 ;
}
Inside your main function, you defined the int *a pointer variable:
int main(){
int N, i, Planet, *a,junk;
But then you dereferenced the pointer without having previously allocated any memory for it, nor setting it to point to something meaningful:
*a = N;
This results in undefined behavior.
What you probably wanted is to make a point to N?
If so, this is the correct syntax:
a = &N;
Now you can use *a to write some content into N.
P.S.
As a general rule, I'd suggest you to declare one variable per line, and initialize pointers to NULL, e.g.:
int man() {
int *a = NULL;
...

What is the reason for the occurence of a segmentation fault in this case, when I assign pointer in a function

This is the code here:
#include<stdio.h>
void assign (int *a1, int *a2) {
a1 = a2;
}
int main() {
int *a; int b; int *c; int d;
b = d = 5;
a = &b;
printf("%d", *a);
assign(c, &d);
printf("\n%d", *c);
return 0;
}
It's fine when I assign pointers manually in the main() function, but the segmentation fault appears when I assign it in the function. Why is this so?
The function assign has no effect. All it's doing is performing a local assignment which has no effect on the caller. As a result, c is undefined in main and you get a segmentation fault.
In order for assign to do what you intend, you have to pass it the address of c, then do a pointer assignment in assign.
Try the following:
#include <stdio.h>
void assign (int **a1, int *a2) {
*a1 = a2;
}
int main() {
int *a; int b; int *c; int d;
b = d = 5;
a = &b;
printf("%d\n", *a);
assign(&c, &d);
printf("%d\n", *c);
return 0;
}
The output is:
5
5
I also moved the newlines to the end of the format strings, which is the normal place to put them.
c is passed by value into the function assign. This means that modifying a1 from the function will not affect c.
To get the expected results, pass c by reference, i.e, pass the address of c:
assign(&c, &d);
and make slight modifications to the function:
void assign (int **a1, int *a2) {
*a1 = a2;
}
and you are good to go! :-)
Arguments are passed by value in C, so modyfying a1 in assign() won't affect c in main().
c remains uninitialized and it has automatic storage duration, so its value is indeterminate.
Then, you used this inderminate value in printf("\n%d", *c);.
This invokes undefined behavor and the program just happened to cause segmentation fault.

C function with pointers work on one computer, and doesn't work on another

#include <stdio.h>
void swap (int *a, int *b)
{
int *tmp;
*tmp = *a;
*a = *b;
*b = *tmp;
}
int main ()
{
int x = 5;
int y = 7;
swap (&x,&y);
printf ("\n x = %d \n y = %d \n",x,y);
}
I'm using codeblocks, and this code won't work, and I don't understand why... On one computer it works perfectly but on the other it won't run at all.
Any help?
Thanks in advance.
int tmp;
tmp = *a;
*a = *b;
*b = tmp;
What you need is a variable tmp to store the value and not a pointer *tmp.
The below code really a poor way of doing this but
int *tmp = malloc(sizeof(int));
*tmp = *a;
*a = *b;
*b = *tmp;
Once done please free the memory using
free(tmp);
Gopi already corrected your code - adding on to the previous answer - i think this is good to know information for a newbie:
Section 4.1 states:
An lvalue (3.10) of a
non-function, non-array type T can be
converted to an rvalue. If T is an
incomplete type, a program that
necessitates this conversion is
ill-formed. If the object to which the
lvalue refers is not an object of type
T and is not an object of a type
derived from T, or if the object is
uninitialized, a program that
necessitates this conversion has
undefined behavior. If T is a
non-class type, the type of the rvalue
is the cv-unqualified version of T.
Otherwise, the type of the rvalue is
T.
When you try to dereference and uninitialized pointer the behavior is undefined. Undefined means anything can happen - there is no guarantee. So you can get different behavior in different environments.
From Wiki Making pointers safer
A pointer which does not have any address assigned to it is called a wild pointer. Any attempt to use such uninitialized pointers can cause unexpected behavior, either because the initial value is not a valid address, or because using it may damage other parts of the program. The result is often a segmentation fault, storage violation or wild branch (if used as a function pointer or branch address).
What you did here:
int *tmp;
*tmp = *a;
is that you created a pointer to int which is not pointing to anything - basically it contains some junk value (could be your pincode even - who knows).
Your mistake was to use uninitialized memory. Always allocate memory to a pointer before using it. Next, don't forget to free the allocated memory after you're done with it.
Also, you should add return 0; at the end of your main() function.
If you don't mind a second opinion, check the below code.
#include <stdio.h>
#include <stdlib.h>
void swap (int *a, int *b)
{
int *tmp = malloc(sizeof(*tmp));
*tmp = *a;
*a = *b;
*b = *tmp;
free(tmp);
}
int main ()
{
int x = 5;
int y = 7;
swap (&x,&y);
printf ("\n x = %d \n y = %d \n",x,y);
return 0;
}
If you want to use pointers, although it does not make any sense at all
void swap(int *a, int *b)
{
int tmp[1];
*tmp = *a;
*a = *b;
*b = *tmp;
}
here tmp is not strictly a pointer, but you can use the * indirection operator on it.
Or
void swap(int *a, int *b)
{
int value = *a;
int *tmp = &value;
*tmp = *a;
*a = *b;
*b = *tmp;
}
Or you can use malloc as Gopi already pointed out.
If you want to use pointers, then do use pointers:
#include <stdio.h>
void swap (int ** ppx, int ** ppy)
{
int * p = *ppx;
*ppx = *ppy;
*ppy = p;
}
int main (void)
{
int x = 5;
int y = 7;
int * px = &x;
int * py = &y;
printf ("\nx = %d\ny = %d\n", *px, *py);
swap (&px, &py);
printf ("\nx = %d\ny = %d\n", *px, *py);
return 0;
}
Result:
x = 5
y = 7
x = 7
y = 5

How can I test this C function

I got a weird question to do as an exercise :
Write a function which take a pointer of a pointer of a pointer of a pointer of a pointer of a pointer of a pointer of a pointer of a pointer of an int as a parameter and assign a value to it.
I think the function I wrote is right (please correct if it's not) but how can I test it ?
void function(int *********anInt)
{
*********anInt = 5;
}
I tried :
int main(void) {
int *********nbr = malloc(sizeof(int));
function(nbr);
printf("%d", *********nbr);
}
But I get a segfault, I just learned about malloc and pointers so I don't fully understand it.
Of course, you can test it, although it looks weird.
#include <stdio.h>
void function(int *********anInt)
{
*********anInt = 5;
}
int main()
{
int n = 0;
int *p1 = &n;
int **p2 = &p1;
int ***p3 = &p2;
int ****p4 = &p3;
int *****p5 = &p4;
int ******p6 = &p5;
int *******p7 = &p6;
int ********p8 = &p7;
function(&p8);
printf("%d\n", n);
return 0;
}
Try
int main() {
int *********nbr;
nbr = malloc(sizeof(int********));
*nbr = malloc(sizeof(int*******));
**nbr = malloc(sizeof(int******));
***nbr = malloc(sizeof(int*****));
****nbr = malloc(sizeof(int****));
*****nbr = malloc(sizeof(int***));
******nbr = malloc(sizeof(int**));
*******nbr = malloc(sizeof(int*));
********nbr = malloc(sizeof(int));
function(nbr);
printf("%d", *********nbr);
}
You'll need a ridiculous main program to go with the assignment from hell!
int main(void)
{
int l0 = 0;
int *l1 = &l0;
int **l2 = &l1;
int ***l3 = &l2;
int ****l4 = &l3;
int *****l5 = &l4;
int ******l6 = &l5;
int *******l7 = &l6;
int ********l8 = &l7;
printf("%d %d %d %d %d %d %d %d %d\n", l0, *l1, **l2, ***l3, ****l4, *****l5,
******l6, *******l7, ********l8);
function(&l8);
printf("%d %d %d %d %d %d %d %d %d\n", l0, *l1, **l2, ***l3, ****l4, *****l5,
******l6, *******l7, ********l8);
return 0;
}
Untested: maybe I didn't count something right, but the general idea is about correct. This is a torture test — for innocent C programmers and for compilers.
An int** is a pointer that points to a pointer:
int myInt;
int* pInt = &myInt;
int** ppInt = &pInt;
An int*** is a pointer that points to a pointer that points to a pointer:
int*** pppInt = &ppInt;
To test your function, you need to carry this on and on, the right number of times.
See md5's solution, however it lacks explaination
Explained:
The reason your test program didn't work is because malloc returns a void* which is simply a memory address (a pointer). You assigned this to an int*****... which means when the program tries to dereference down to the actual int what it's doing is first taking the memory address of the int and dereferencing it (which is okay) but after this since your value (5) is now the value it then derefences that, which should come back with your segfault.
Think of the assignment as nested dereferences:
int ********p8 = *anInt; // p8 == 5
int *******p7 = *p8; // This breaks since dereferencing memory
// address 5 results in a segfault
What was done to avoid this was we actually nested the pointers that way when dereferencing for assignment we have memory addresses (pointers) to dereference to eventually get to the memory address which stores the value.

Memory allocated with malloc does not persist outside function scope?

Hi,
I'm a bit new to C's malloc function, but from what I know it should store the value in the heap, so you can reference it with a pointer from outside the original scope. I created a test program that is supposed to do this but I keep getting the value 0, after running the program. What am I doing wrong?
#include <stdio.h>
#include <stdlib.h>
int f1(int *b) {
b = malloc(sizeof(int));
*b = 5;
}
int main(void) {
int *a;
f1(a);
printf("%d\n", a);
return 0;
}
Yes! a is passed by value so the pointer b in function f1 will be local..
either return b,
int *f1() {
int * b = malloc(sizeof(int));
*b = 5;
return b;
}
int main() {
int * a;
a = f1();
printf("%d\n", *a);
// keep it clean :
free(a);
return 0;
}
or pass a's address
int f1(int ** b) {
*b = malloc(sizeof(int));
**b = 5;
}
int main() {
int * a;
f1(&a);
printf("%d\n", *a);
// keep it clean :
free(a);
return 0;
}
It looks like you're misunderstanding a fundamental part of how C works - namely that it is a 'pass-by-value' language. In order for main() to know about the memory you allocated, you have to get it back out. The following code will do you what you want:
int f1(int **b)
{
*b = malloc(sizeof(int));
**b = 5;
}
int main(int argc, char **argv)
{
int *a;
f1(&a);
printf("%d\n", *a);
return 0;
}
There are a couple differences between this code and yours; first, the signature of f1() has changed, so that it can return the result of the malloc() call in the passed in pointer. Next, the call to f1() has been changed to pass the address of a rather than a itself - important if you want it to be 'filled-in' by f1(), so to speak. Finally, the printf() in main() has been changed to print out the pointed-to value rather than the pointer itself.
The memory itself persists, but it leaks because you're not providing the allocated pointer to the caller. Also, you're printing a when you should be printing *a. Finally, you're not returning an int from f1.
Try:
void f1(int **b) {
*b = malloc(sizeof(int));
**b = 5;
}
int main() {
int *a;
f1(&a);
printf("%d\n", *a);
free(a);
return 0;
}
Lets suppose you assign a value of NULL to a before you call function f1. Now the way f1 is defined it takes its argument(pointer to an int) by value. That is b will be another variable of type int * which will be a copy of a. So b too will have a value of NULL. Now in f1 you change the value by b by assigning it the address of memory allocated dynamically using malloc. Lets say that memory address is 0x123. As a result of this assignment, b has changed its value from NULL to 0x123 but a(in main) continues to hold NULL, because changing b will not change a, as they are two separate variables. As a result of this when you return from function f1 a will remain unchanged.
There are 2 ways to solve this. One you can make the function f1 return the value of the changed b and then assign it back to a in main and two, you can pass the a by address so that any changes made in f1 will affect a in main too.
// f1 now returns the value of b.
int* f1() {
int *b = malloc(sizeof(int));
*b = 5;
return b;
}
int main() {
int *a = NULL;
a = f1(); // assign the return value of f1 to a.
printf("%d\n", *a); // prints 5...not its *a not just a.
return 0;
}
.
// f1 now takes the address of a.
void f1(int **b) {
*b = malloc(sizeof(int)); // you are actually altering a indirectly.
**b = 5;
}
int main() {
int *a = NULL;
f1(&a); // now pass the address of a to f1.
printf("%d\n", *a); // prints 5...not its *a not just a.
return 0;
}
The address int *b is deleted when the function return. To save it, you need to use a pointer of a pointer
int f1(int ** b) {
*b = malloc(sizeof(int));
**b = 5;
}
Your problem is actually not related to malloc, but rather the fact that you're passing the value the pointer currently holds, rather than the address of it. Try the following:
int f1(int ** b) {
*b = malloc(sizeof(int));
**b = 5;
}
int main() {
int * a;
f1(&a);
printf("%d\n", *a);
return 0;
}
By passing the pointer value as you were, there was no way for the value malloc created to be stored into the pointer.

Resources