This question already has answers here:
Segmentation Fault when attempting to print value in C
(3 answers)
Closed 3 years ago.
I'm very new to C, but have no idea why this program breaks. The program compiles and runs if I remove the lines that have to do with i, but if I assign i, I can no longer assign anything to *ptr without the program breaking.
int main(void)
{
int i;
int *ptr;
i = 2;
*ptr = 5;
printf("%d",*ptr);
}
You leave the pointer with uninitialized value. So when you dereference it (*ptr), you access arbitrary place in memory, resulting in a segmentation fault.
Point ptr at something by assigning to ptr itself (not *ptr) an address of a variable (like &i) or some freshly allocated memory (like malloc(sizeof(int))).
Here is the answer for C:
int main(void) {
int i;
int * ptr = (int *)malloc(sizeof(int));
i = 2;
*ptr = 5;
printfn("%d",*ptr);
free(ptr);
}
Alternatively you could for the i and *ptr assignment lines use something like:
int main(void) {
int i;
int * ptr;
i = 2;
ptr = &i;
printfn("%d",*ptr); // should print 2
}
Notice also that the free came out!!!
You declared ptr but didn't make it point to anything. Then you tried to write to what it points to. This is never a good idea. Try making ptr point to i by adding the line
ptr = &i;
before you try to write to *ptr
Before using a pointer in C, you need either to set the pointer to an existing block of memory, you need to allocate memory for it, like this.
int *ptr = (int *)malloc(sizeof(int));
Related
Is it required, or recommended, that every pointer in C be allocated on the heap? For example, is it likely or possible that the following code could produce a segmentation fault?
#include <stdio.h>
int main(void) {
int* p;
*p = 16;
printf("Pointer p = %d\n", *p);
return 0;
}
This code will likely segfault because p is uninitialized and therefore doesn't point to a valid address.
A pointer doesn't necessarily have to point to heap memory. It just needs to point to a valid object. For example:
int x = 4;
int *p = &x;
*p = 5;
printf("x=%d\n", x); // prints 5
It doesn't have to be allocated. You just need to make sure it points to valid memory address, which you didn't in your example.
Since you didn't initialize the pointer, it has some random value and trying to dereference it will interpret this value as a memory address, which is probably going to give you a segmentation fault.
You could instead do something like:
int x; // not initialized, random value in memory
int *p = &x;
*p = 16; //now you are accessing a valid address (x's)
I simply want to assign a pointer to another pointer via the function (same memory address). My code is below:
#include <stdio.h>
void d(int** a)
{
int* val_ptr = malloc(1);
*val_ptr = 5;
printf("%d\n", *val_ptr);
a = &val_ptr;
}
int main()
{
int* a = NULL;
d(&a);
printf("%d\n", *a);
return 0;
}
Output from Link
5
Segmentation fault
Your code has three problems:
Here int* val_ptr = malloc(1);, you allocate 1 byte rather than allocating space for an int. Use the following to fix it:
int* val_ptr = malloc(1 * sizeof(int));
This a = &val_ptr; is not what you want. It changes the local pointer and makes it point to the address of val_ptr. This will not affect the pointer that you've defined in main.
Fix it using
*a = val_ptr;
This way, the pointer in main will also reflect the change and will point to the malloced memory
You should free the allocated memory after its use. Add
free(a);
after the printf in main to free it.
I'm a bit confused as to why the following code crashes:
int main(){
int *a;
int *b;
*a = -2;
*b = 5; //This line causes a crash on my system.
return 0;
}
Shouldn't memory automatically be allocated for two pointers and two integers before run-time because of the declarations?
Or must you always explicitly allocate memory?
No. You've only declared the pointers, not what they point to. The pointers are allocated on the stack, and since you've not initialized them to anything, their values are garbage.
int main() {
int a = 7;
int *p_a; // p_a contains whatever garbage was on the stack at its
// location when main() is called. (Effectively points nowhere).
p_a = &a; // p_a points to (gets the address of) variable a, also on
// the stack.
printf("Before: a = %d\n", a); // prints 7
*p_a = -2;
printf("After: a = %d\n", a); // prints -2
return 0;
}
I would code up the above example, and step through it in a debugger. You'll see what I mean about what p_a is pointing to.
Shouldn't memory automatically be allocated for two pointers and two integers before run-time because of the declarations?
I only see you specifying two pointers. Where are the two integers?
Or must you always explicitly allocate memory?
Pointers have to point to something. Either local variables on the stack, or malloc'd memory from the heap.
In this code:
int* a;
*a = -2;
a is an uninitialized pointer, dereferencing of which produces undefined behavior, that you were luckily able to observe as a crash of your application.
You need to initialize the pointer (make it point to the valid memory) before you dereference it (i.e. before you use *, the dereference operator):
int a;
int* pA = &a;
*pA = -2;
Consider
int m;
int n;
m = n;
This is invalid because you're trying to use n but you haven't assigned a value to it. Now:
int *a;
*a = -2;
Likewise, this is invalid because you're trying to use a but you haven't assigned a value to it. The value of a is not an int, it's a pointer to int. For example,
int someint;
a = &someint;
*a = -2;
puts -2 into someint. Without the assignment to a, the place to put -2 is undeterminable. Also,
a = malloc(sizeof(int));
*a = -2;
Here, a is given the value of the address of some location in the heap; -2 goes into that heap location.
Perhaps an analogy would be helpful:
Consider the phrase "her dog". This is a reference to someone's' dog, but it won't do to tell me "give her dog a bone" if you haven't told me who she is. Similarly, "pointer to an int" doesn't tell the system which int it is.
Your *a and *b pointers are not initializated properly.
Try this one:
int my_a;
int my_b;
int *a;
int *b;
a = &my_a; // init the pointer a to the direction of my_a int variable
b = &my_b;
*a = 3; // set the my_a value via pointer
*b = 2;
You have just declared pointers but you haven't initialized them. So, you can't be sure that *b = 5 is causing the program to crash. It could be *a = -2 as well. To fix it, you should initialize your pointers as well.
int aval = -2;
int bval = 5;
int *a = &aval; // declared and initialized pointers
int *b = &bval;
// Now you can change the value using the pointer
*a = 15;
*b = 20;
#include <stdio.h>
int main(void)
{
int* a;
*a=20;
printf("%i\n",*a);
return 0;
}
I have the code above. when the code in runtime, I always get the error message "filename.exe has stop working". Why?
You did not allocate any memory for the pointer to point at. You can do so like this:
int *a = malloc(sizeof(*a));
or like this:
int value;
int *a = &value;
If you allocate with malloc then you'll want to call free on the pointer when you are finished using it.
Accessing an uninitialized pointer leads to undefined behaviour. In your program it led to segmentation fault, one very common outcome of uninitialized pointer access.
In int* a; a's default value is garbage, and points to an invalid memory, you can't assign to that. And assignment like *a=20; this is causes an undefined behavior at run time. (syntax wise code is correct so compiled) you may some time get a seg-fault too.
either do:
int i;
int *a = &i; // a points to a valid memory that is i
*a = 20;
or with dynamic memory allocation using calloc() or malloc() functions.
int *a = malloc(sizeof(int));
*a = 20;
Remember dynamic allocated memories we have to deallocate (free) explicitly when we have done with that.
You have wild pointer, either assign memory to it using malloc
int* a = malloc(sizeof(int));
or use a stack variable
int b = 0;
int *a = &b;
*a=20;
The problem is in your assignment
*a = 20.
You can't allocate a value to a pointer variable like that.
int b = 20;
a = &b;
Thanks,
Santhosh
I am trying to have a function take some integer pointers passed from my main() function and assign values to them. However, my program crashes when assigning values. Here is my code:
int computeMoveLocation(int* r, int* c, char* board)
{
//some code up here
*r = 0; //This breaks the program
*c = 0;
}
I'm not trying to change the address of the pointer--I'm trying to change the value of the integer being pointed to. However, I am apparently doing something wrong.
Any help would be greatly appreciated.
EDIT:
Here is the relevant code from main(). Please let me know if I should include anything else as well.
int main()
{
//initialization code
//...
while (1)
{
switch (MACHINE_STATE)
{
case COMPUTER_MOVE :
{
//check rows for three Xs
//check columns for three Xs
//check diagonals for three Xs
//otherwise, move anywhere else
int *r, *c;
computeMoveLocation(r, c, board);
computerMove(*r,*c, board);
PREVIOUS_STATE = COMPUTER_MOVE;
MACHINE_STATE = HUMAN_MOVE;
break;
}
//Other cases
}//end switch
}//end while
}//end main
You are passing in pointers but you didn't allocate memory. So they are pointing at a random location in memory.
int computeMoveLocation(int* r, int* c, char* board) {
//some code up here
*r = 0; //This breaks the program
*c = 0;
}
Bad main :
int main() {
int *r;
int *c;
char *board;
// bad, passing in pointers but didn't allocate memory
computeMoveLocation(r, c, board);
return 0;
}
Good main #1:
int main() {
int r = 5;
int c = 5;
char board = 'a';
// fine, passing address of variables on stack
computeMoveLocation(&r, &c, &board);
return 0;
}
Good main #2:
int main() {
int *r = malloc(sizeof(int));
*r = 5;
int *c = malloc(sizeof(int));
*c = 5;
char *board = malloc(sizeof(char));
*board = 'a';
// fine, passing pointers that point to heap
computeMoveLocation(r, c, board);
free(r);
free(c)
free(board);
return 0;
}
int *r, *c;
computeMoveLocation(r, c, board);
computerMove(*r,*c, board);
You define a pointer but don't make it point to anything. Thus, it is a wild or uninitialized pointer; accessing *r as you do in computeMoveLocation will cause undefined behaviour (in your case, a crash).
You have to either initialize the pointer to point at something known, or just pass the address of an existing int:
int r, c;
computeMoveLocation(&r, &c, ...);
or
static int x, y; // static: only one instance of the variable exists
int *r = &x; // initialize pointers
int *c = &y;
computeMoveLocation(r, c, ...);
or
int *r = malloc(sizeof(int));
int *c = malloc(sizeof(int));
computeMoveLocation(r, c, ...);
In that last case, make sure to free the memory afterwards.
You can always pass a pointer and modify the value that the pointer is pointing to. That is how pointers are supposed to be used. But, you should also be careful to see if the pointer does really points to something or not. The pointer should contain a valid address, the value at whose location you can change. If you don't ensure that, then Undefined Behavior will result.
For Example, when you call your computeMoveLocation function, the address which you are passing should either be of stack or of heap. You can see the code below to understand it.
First possibility
int r, c;
char board;
computeMoveLocation(&r,&c, &board);
Second Possibility
int *r, *c;
char *board;
r = malloc(sizeof(int));
c = malloc(sizeof(int));
board = malloc(sizeof(char));
computeMoveLocation(r,c,board);
Please note that char * is also generally used to pass an address to array of charaters, but, in a such a usage, generally it is ensure that it is null terminated or an accompanying length of the array is also passed.
You can anyway get more details on passing aroung pointers by a simple google search.
EDIT
Now, that you have posted your code which calls computeMoveLocation, you see that you should modify your code according to the Second Possibility shown above, since you are declaring r and c as pointers or you should declare them as integers and call as per the First Possibility shown above. But, you are not doing the same which causes the undefined behavior.
Also, in the above examples, I have allocated memory for board, but, in your case, if it originates at some other place and if it has been handled appropriately there, then it need not be malloced.