This question already has answers here:
Crash or "segmentation fault" when data is copied/scanned/read to an uninitialized pointer
(5 answers)
Closed 1 year ago.
#include <stdio.h>
#include <stdlib.h>
void main()
{
int i;
int *as[2];
for(i=0;i<2;i++)
{
*as[i]=i;
printf("%d\n",*as[i]);
}
}
This is my code. I am expecting to print values 1
2
But when I run the code the console prints nothing. What have I done wrong?
The * character in C language is not a simple decoration. It declares a pointer that has to point to something. Here you declared an array of two pointers, but never initialized the pointer themselves. And dereferencing an uninitialized pointer is explicitely Undefined Behaviour (the hell for C programmers). If you want to process integers, get rid of the pointers:
int as[2];
for(i=0;i<2;i++)
{
as[i]=i;
printf("%d\n",as[i]);
}
Or if you really want to process pointers, ensure that they are initialized to point to a valid object:
int *as[2];
int data[2]
for(i=0;i<2;i++)
{
as[i] = &(data[i]); // Ok, as[i] now points to a valid integer
*as[i]=i;
printf("%d\n",*as[i]);
}
BTW, the idiomatic way to get the address of an element of an array would be:
as[i] = data + i;
Related
Please explain (reason for the output) what happens as a result of running the two segments of code. Please explain their difference too. There are two versions of setArr(int, int) as explained below...
#include <stdio.h>
void setArr(int, int);
int *arr[10]; // array of 10 int pointers
int main(int argc, char *argv[]) {
int i;
setArr(0, 0);
setArr(1, 100);
setArr(2, 200);
setArr(3, 300);
setArr(4, 400);
for (i = 0; i < 5; i++)
printf("arr[%d]: %d\n", i, *arr[i]); /* should be 0,100, 200,300,400 */
return 0;
}
Versions of setArr
Version A
void setArr(int index, int v) {
int i = v;
*arr[index] = i;
}
Output: Segmentation fault (core dumped)
Version B
void setArr(int index, int v) {
int i = v;
arr[index] = &i;
}
Output:
arr[0]: 400
arr[1]: 32748
arr[2]: 32748
arr[3]: 32748
arr[4]: 32748
I presume the values from running Version B are just random values.
I am fairly new to pointers I have knowledge in Java, so please explain it as beginner friendly as you can :)
You are hitting a lot of undefined behavior scenarios, but I will explain what is likely happening.
arr is an array of 10 pointers to integers.
int * arr[10]; // array of 10 int pointers
And when declared as a global variable, all of those pointers are going to be zero-initialized - so hence, it's an array of 10 NULL pointers.
So this line in version A, is dereferencing the address at arr[index]:
* arr[index] = i;
Is effectively saying this:
*(NULL) = i;
And that will certainly crash consistently.
In Version B, you have it as:
int i = v;
arr[index] = &i;
So now you are correctly assigning a pointer to a slot in the array. However that address getting assigned is to a local stack variable, i, which goes out of scope as soon as the function returns. So when you print the value at that address, it's most certainly been clobbered from other calls writing on top of the stack. (Or technically this "undefined behavior" of accessing a memory address of a stack variable that has gone out of scope.)
Better:
void setArr (int index, int v){
arr[index] = malloc(sizeof(int));
*arr[index] = v;
}
The above allocates memory for the address that you want to copy that value into. You're on your own for how to free that memory.
Alternatively:
Just declare arr as an array of integers instead of pointers:
int arr[10];
void setArr (int index, int v){
arr[index] = v;
}
And then print normally without the * deference thing on arr.
printf("arr[%d]: %d\n", i, arr[i]);
Version A says "the contents of an undefined pointer equals i" - undefined behavior = crash. Basically you are trying to write to some unknown location in memory.
Version B says "Some pointer = some address" - still undefined behavior as &i goes out of scope, but it is still an address and so it "kind of works". Here you are writing to "good" memory locations, but reading from bad ones.
in first case, you have defined the "array of pointers" to integer. They are not integer pointers. Either you will have to allocate memory (preferably using melloc/calloc functions) before storing any value to them OR you can define the array of integer like this:
int (*a)[10]
The following link may show you some idea about it: Difference between *ptr[10] and (*ptr)[10]
In second case, you are saving the address of integer into integer pointer, which is ok, but int i is local variable to function setArr(). This will therefore, the value of int i will be dereferenced every time the function setArr() exits. Therefore you are getting undefined behavior for 2nd case. Either you can use static int i OR use global variable (not preferred) OR use pointer to integer assignment.
This question already has answers here:
Is there a reason why an array name is not an lvalue?
(4 answers)
Is an array name a pointer?
(8 answers)
Closed 6 years ago.
#include <stdio.h>
int main(void) {
int values[10];
int a = 10;
values = &a;
printf ("the value is = %i.\n\n", *values);
return 0;
}
This code is written just for experimenting on pointers, I have just started learning it.
My question is that if the name of the array is a pointer then why cant we copy some other variable's address into it.
The error that it gave was "assignment to expression with array type"
please explain it in simple way.
Arrays cannot be assigned to. You can store values into array elements and you can store array addresses into pointers, but arrays themselves cannot appear on the left side of an assignment operator.
You can change values to a pointer:
#include <stdio.h>
int main(void) {
int *values;
int a = 10;
values = &a;
printf ("the value is = %i.\n\n", *values);
return 0;
}
or you can store a into values[0]:
#include <stdio.h>
int main(void) {
int values[10];
int a = 10;
values[0] = a;
printf ("the value is = %i.\n\n", *values);
return 0;
}
think of arrays as parking lots:
You can store a car into a parking spot (array element)
You can write the lot number on a piece of paper (lot pointer, you can retrieve the car by giving that to the operator).
You cannot store a parking lot into another parking lot, they are not moveable.
Array designators are non-modifiable lvalues. You may not use an array designator in the left side of the assignment expression.
Thus the compiler issues an error for this statement
int values[10];
int a = 10;
values = &a;
^^^^^^^^^^
This question already has answers here:
How to find the size of an array (from a pointer pointing to the first element array)?
(17 answers)
Closed 6 years ago.
#include <stdio.h>
int a[3] = {1,2,3};
void cal(int* item){
printf("Length(inside) is %lu\n", sizeof(item)/sizeof(item[0]));
}
int main(){
printf("Length(outside) is %lu\n", sizeof(a)/sizeof(int));
cal(a);
}
The code above comes out with the result that
Length(outside) is 3
Length(inside) is 2
However, it is wrong, because both of them should be 3, what's wrong with my code?
First of all, you should be using %zu fomat specifier to print the result.
Secondly, when passed to a function as argument, array name decays to the pointer to the first element, so the sizeof(item) will not work as expected.
Basically what you're doing is sizeof (int *)/ sizeof (int) and in your environment, it is likely that a pointer occupies 8 bytes and an int takes 4, so you get this result.
This is because the array decays into a pointer when it is passed to a function.
So essentially what you are doing is
sizeof(int*)/sizeof(int);
What you can think is the difference between
int a[5];
sizeof(a)/sizeof(a[0]); //this works
and
int a[5];
int* p = a;
sizeof(p)/sizeof(p[0]);
This question already has answers here:
Is an array name a pointer?
(8 answers)
Closed 8 years ago.
Suppose an array int a[10].
Why we can't do a=a+1 ? but the same is valid with a pointer variable.
int *ptr = a;
ptr = a+1;
How are both scenarios seen practically?
Because array locations are constant.
You can't change the value of a, since that represents the starting address of the array. Moving it doesn't make any sense.
With int *ptr; your variable ptr is just a single pointer and can of course be set to point to anywhere you like.
There's no contradiction here. It's a little like with functions, the name of a function evaluates to its address (called "a function pointer") but you can't assign to that either.
Because Array name is constant pointer pointing to its first element.You cannot change the value of constant variables,i,e what the const keyword is used for.
int a[10]; //here a (array variable is Const i,e you Cannot a=a+1)
int* const p=&a[0]; //here Also Same,Now p is Const i,e you Cannot p=p+1.
But Here:
int* pp=&a[0];//Here pp=pp+1 will work, Because pp is not Const.
You can if the array is a function argument
#include <stdio.h>
int rval(int a[10]) {
a = a + 1;
return a[0];
}
int main(){
int a[10] = {0,1,2,3,4,5,6,7,8,9};
printf ("%d\n", rval(a));
return 0;
}
Program output
1
This question already has answers here:
Modifying String Literal [duplicate]
(4 answers)
Closed 8 years ago.
Where is the problem? When running, the application crashes...
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
void test(char* x) {
(*x)++;
}
int main() {
char* x = "xD";
test(x);
puts(x);
getch();
return 0;
}
You are Trying to modify a string literal that is stored in a read-only memory adress, because with char* x = "xD"; you declare a pointer to that kind of data. use this char x [] = "xD"; instead, that is NOT a pointer, is an array that you are allowed to modify because it is stored in the stack. or if you want to use a pointer you need to allocate memory for it.
it crashes in the line (*x)++; because x Points to a read only Memory due to the Definition char* x = "xD";.
Change it to char x[] = "xD";. so x is an Array and it´s values can be changed