i want to print the value which contain in the multidimensional array.I know that if we write something like arr[3][4] then arr[0] is the pointer to the first element in the that multidimensional array.
I want to ask why this code give me garbage value after the program print the number containing in the multidimensional array?
this is the code:
#include <stdio.h>
#define ROW 3
#define COLL 4
int main(void) {
int arr[ROW][COLL]={{1,2,3,4},
{5,6,7,8},
{9,10,11,12}};
int *ptr;
for(ptr=arr[0];ptr<arr[ROW]+COLL;ptr++){
printf("%d ",*ptr);
}
printf("\n");
return 0;
}
this is the result when i compile the above code:
1 2 3 4 5 6 7 8 9 10 11 12 -1079481492 134513936 0 -1079481352
but after changing the for loop to the following:
for(ptr=arr[0];ptr<=arr[ROW-1]+COLL-1;ptr++)
the code work and give the exact number which contain in the multidimensional array.
Because arr[ROW] is an out-of-bounds access. The last valid position in arr is arr[ROW-1]. Thus the first version of your code invokes undefined behaviour.
The pointer to the last element is
arr[ROW-1] + COLL - 1
So you loop should be
for (ptr = arr; ptr < arr[ROW-1] + COLL; ptr++) {
Elements of an array are indexed from 0 so the last element in your matrix is arr[ROW-1][COLL-1].
When your pointer reaches arr[2] + COLL there is no such element because the second coordinate of the last element in last row is [COLL-1].
Elements of an array are stored in 1D so arr[0] + 4 is acctualy arr[1][0].
When you increment ptr++ it tells the compiler to access the next memory location after the current. So, when ptr points to a[0] + 4 it works because the compiler access the fifth value after a[0][0] which is actually the first value in the next row, arr[1][0], because their memory locations are next to each other.
When your ptr points to arr[4] + i, i = 0, 1, 2, 3 you get bad output because those elements are not in your array.
Because your first element, 1, is at arr[0]+0,
5 is at arr[1]+0,
9 is at arr[2]+0,
10 is at arr[2]+1,
11 is at arr[2]+2,
and 12, which is the last element of your array is at arr[2]+3.
but your for loop keeps moving even after the array ends, that is, until the memory location arr[3]+4 is reached. Giving you four garbage values because we have stored nothing in the memory after arr[2]+3.
so the for loop should be like:
for (ptr=arr; ptr <= arr[ROW-1]+COLL-1; ptr++);
which is equivalent to:
for (ptr=arr[0]; ptr <= arr[ROW-1]+COLL-1; ptr++);
as arr[0] and arr point to the same location in memory.
NOTE- try reading how memory is allocated in arrays of multiple dimensions.
Related
Hello I am learning c in school and having a little confusion on this problem.
That is,
b is two d array, and I am trying to implement around printing values and the adress,
but why is *(b+1) giving the same thing as b+1?
I thought *(b+1) would give the value of the first element of the second row.
and if I change printf("%p\n", *(b+1)) to printf("%d\n", *(b+1)), it just gives a garbage value.
Why is it working like this?
I appriciate any feedback! thank you
int main()
{
int b[3][4] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
printf("b:\n");
print_2d_array(3, 4, b);
printf("\n");
printf("%p\n", b);
printf("%p\n", *(b+1));
printf("%p\n", b+1);
return 0;
}
Output is like this,
b:
0 1 2 3
4 5 6 7
8 9 10 11
0x7ffeecee6730
0x7ffeecee6740
0x7ffeecee6740
The question you have asked essentially boils down to a question about the nature of an array and the address of an array, which is a fairly well covered topic (see this for example). However, you likely confused yourself with the pointer arithmetic, so this answer tries to clarify some of that.
In C, when array object is used in an expression, its value and type becomes the same as the pointer to its first element.
In your case, you have:
int b[3][4] = { /* ... */ };
/* ... */
printf("%p\n", *(b+1));
printf("%p\n", b+1);
If we consider the last print statement,b in the expression b + 1 becomes the same as &b[0] + 1, and this would be the same as &b[1].
When we consider the print statement before the last one, we note that *(b+1) is defined to be the value b[1]. However, the result of that expression is an array of 4 int. That array now takes on the value and type of its first element, which would be &b[1][0].
Since you need to be able to find the address of the first element of an array from the array itself, the address of an array, &b[1], has the same pointer value as the address of its first element &b[1][0].
However, &b[1] and &b[1][0] have different types. The former is a pointer to an array, while the later is a pointer to an int.
For additional information, I encourage you to read the linked question at the top of this answer for more about arrays and the address of arrays.
*why is (b+1) giving the same thing as b+1?
The output address is numerically same but their type is different.
The type of *(b+1) is int [4] whereas the type of b+1 is int (*)[4].
*(b+1), when used in an expression, will convert to address of first element of second row1):
*(b + 1) -> b[1] -> ((b[1]) + (0)) -> &(*((b[1]) + (0))) -> &b[1][0]
and b+1 will give address of second row.
Address of an array and address of first element of that array are numerically same but their type are different.
*I thought (b+1) would give the value of the first element of the second row.
*(b+1) will give the second element of 2D array b which is nothing but a 1D array of 4 integers.
To access the first element of second row using *(b+1), you can do:
(*(b+1))[0]
To access the second element of second row using *(b+1), you can do:
(*(b+1))[1]
third element ....
(*(b+1))[2]
and so on .....
Note that *(b+1) is equivalent to b[1]1). So,
(*(b+1))[0] is equivalent to b[1][0]
(*(b+1))[1] is equivalent to b[1][1] .. and so on
Hope this clarifies your doubt.
1 ) From C Standards#6.5.2.1
The definition of the subscript operator [] is that E1[E2] is identical to (*((E1)+(E2)))..
I was given this function and I need to explain what it does without other context.
What my interpretation is: The address of the first element of an array is inputted into arrFunc with some length L1, and an integer pointer p is declared and initialized to point to the first element of arr1.
The while loop is what confuses me. My interpretation is (and I'm a beginner when it comes to programming) is that if the contents of p (which I believe contains the address of the first element of arr1) is less than the address of the last element of arr1, then increment the value inside the first element by 5, then increment p to go on to the next element of the array. The biggest thing that confuses me about the while loop is the comparison of two addresses (p<arr1+L1).
I guess my other question is, is the condition in the while loop comparing the two addresses, or is it comparing the values stored in those addresses?
void arrFunc(int *arr1, int L1)
{
int *p = arr1;
while(p< arr1 + L1)
{
*p+=5;
p++;
}
}
The function adds 5 to the elements of the provided array, but only to the first L1 elements (might not be the whole array).
To answer the second question, about adding an int to a pointer, in terms of memory C will manage to add the right amount based on an element size ; meaning it doesn't simply add the int to the address, it adds
sizeof(*array) * intValue
It actually adds the size of an array element multiplied by that integer value. Here it adds sizeof(int) * L1 to get
arr1 + L1
to be compared with p. (p++, similarly, is incremented, in terms of addresses, by sizeof(int)).
This function takes an array of size L1 and add 5 to each of the element. So if an array of size 4 like following is inputted
10 20 30 40
After executing this function the output will be
15 25 35 45
Consider the following C program:
#include <stdio.h>
void swap(int []);
int main(void) {
int a[3] = {1, 2, 3};
swap(a);
printf("%d %d %d\n", a[0], a[1], a[2]);
swap(&a[1]);
printf("%d %d %d\n", a[0], a[1], a[2]);
return 0;
}
void swap(int x[]) {
int temp = x[0];
x[0] = x[1];
x[1] = temp;
}
Can anyone explain why the following code gives an output
2 1 3
2 3 1
rather than
2 1 3
1 2 3
I understand that swap(a) swaps a[0] and a[1]. But I'm not so sure how swap(&a[1]) works. In both cases we are passing the array a into the function swap, are we not? So my hypothesis was that swap(&a[1]) should again swap a[0] and a[1], giving us back the original order 2 3 1.
EDIT: This code was written as intended. I just wanted to see what happens if we pass an address of an element other than the first element into the function. Apparently if I pass &a[n] into the function, it disregards all elements before a[n] and treats a[n] as the first element?
Your swap function takes and address of an integer as input and swaps element at that address with element at next address.
swap(a) is same as swap(&a[0])
It will swap element at index 0 with element at index 1.
Now your array becomes {2,1,3}
swap(&a[1]) swaps element at index 1 with element at index 2.
So your array now becomes {2,3,1}
Remember when you pass an array actually you are passing address of element at index 0 (&a[0]).
Because when you swap first time you sent an array starting with 0 index then it exchanges 0th and 1st index values means at first swap, array becomes {2,1,3} then again you sent this array starting with 1 index means you sent only two values {1,3}, then that values gets exchanges. In this case x[0] = 1 & x[1] = 3, that is why the output came as {2,3,1} here 2 remains as it is.
In the first call swap(a); you are passing the entire array (actually a pointer to the first element.) So you are swapping elements 0 and 1, which are 1 and 2, respectively, therefore your first output is 2 1 3.
In the second call swap(&a[1]); you are passing the address of the second element in the array, and in your swap function you are therefore swapping the second and third elements, at indices 1 and 2, which are 1 and 3, respectively. That's why your answer after the second iteration is 2 3 1.
Possibly what you meant was
swap(&a[0]);
This will swap the values at indices 0 and 1, which will give you the desired output of 1 2 3.
In your code before the first println statement you are passing a complete array to the parameter of the fuction but in the next you are just passing a single value of location of a[1] which make bit confusing for the function because it has only a single value to swap or it might be as first you passed a zero(0) index or the array to swap with the next time you pass first 1 index of array to swap with which means [1,3 to swap] so pass complete in next statment as this
swap(a);
printf("%d %d %d\n", a[0], a[1], a[2]);
swap(a);
printf("%d %d %d\n", a[0], a[1], a[2]);
return 0;
this will generate your desire answer
I'm a c beginner and i've a problem (as usual). I wrote this simple program:
#include <stdio.h>
#define SIZE 10
main()
{
int vettore[9];
int contatore1,contatore2;
for(contatore1 = 0; contatore1 <= 9; ++contatore1)
{
vettore[contatore1] = contatore1*2;
}
printf("%d\n\n", vettore[9]);
for(contatore2 = 0; contatore2 < 10; ++contatore2)
{
printf("%d\n", vettore[contatore2]);
}
printf("\n%d\n", vettore[9]);
return 0;
}
The output of this program is:
18
0
2
4
6
8
10
12
14
16
9
10
Why the value of vettore[9] changes 3 times? And why it has the correct value only on the first line of the output? thank you :)
C arrays are zero based so valid indexes for a 9 element array are [0..8]. You are writing beyond the end of your array. This has undefined results but is likely corrupting the next stack variable.
In more detail... vettore has 9 elements, which can be accessed using vettore[0] ... vettore[8]. The final iteration of your first loop writes to vettore[9]. This accesses memory beyond the end of your array. This results in undefined behaviour (i.e. the C standard does not specify expected outcome here) but it is likely that the address of vettore[9] is the same as the address of contatore2, meaning that the latter variable is written to.
You have a similar problem in the next loop which prints more elements than vettore contains.
You can fix this by changing your loops to
for(contatore1 = 0; contatore1 < 9; ++contatore1)
for(contatore2 = 0; contatore2 < 9; ++contatore2)
Note that it would be safer if you changed to calculating the size of the array instead, by using sizeof(vettore)/sizeof(vettore[0]) in the exit test of your loops in place of hard-coding 9.
Your array vettore has 9 elements, but by referencing vettore[9], you're actually referencing the 10th element (since element indexing starts from 0). So it's some random location on the stack, without a well-defined value.
The solution is to index only up to vettore[8], or define vettore to have size 10.
check this out:
for(contatore2 = 0; contatore2 < 10; ++contatore2)
{
printf("%d\n", vettore[contatore2]);
}
you are displaying 11 elements of the vettore array (which is defined as a 9 ints array). I think that the error is in the random allocation on the stack
the vettore size as you defined is 9
int vettore[9];
and in your loop you start from 0 till 9 so you are playing with 10 elements of the array and not 9 (size of the array)
you should define the array with size 10
int vettore[10];
Arrays (i.e. "vectors") start at index zero NOT one; it's contents may be, for example, 5 but it will occupy index locations of 0,1,2,3,4....
[1][2][3][4][5] <- Five items
0 1 2 3 4 <- Their respective locations in the array
Same goes for visualizing characters in strings.....(technically the location in memory contains ASCII value-- look into that for fun ;) )
['c']['a']['t'] <- Three items
0 1 2 <- Their index location in the array
I suggest Kochan's C Programming book; great for starting out!!!
i have a program about 2-D arrays
base adress is 8678
#include<stdio.h>
#include<conio.h>
main()
{
int arr[3][3]={
{83,8,43},
{73,45,6},
{34,67,9}
};
printf("%d ",&arr+1); //points to 8696
printf("%d ",arr+1); //points to 8684
return 0;
}
what is the difference between arr+1 and &arr+1?
Well, they're different things. arr decays in most contexts to a pointer to the first element of your array - that means a pointer to the first 3-element row in your 2D array: type int (*)[3]. arr + 1, then, points to the second row in the array.
&arr is the address of the array itself (type int (*)[3][3]), so &arr + 1 points to memory just past the end of the entirety of your 2D array.
You can confirm this behaviour easily by printing differently. Specifically, printing the offsets to the new pointers rather than the values themselves will help clear things up. The output from your program from these print statements:
printf("%ld\n",(intptr_t)(&arr+1) - (intptr_t)arr);
printf("%ld\n",(intptr_t)(arr+1) - (intptr_t)arr);
Will be the decimal offsets to &arr+1 and arr+1 respectively. Here's the output from a test run I just made:
36
12
36 matches up: 3 rows × 3 columns × 4 bytes per entry = 36 bytes. So does the 12: 1 row × 3 columns × 4 bytes per entry = 12 bytes.
Note - you're also printing pointers using %d, which is wrong. You should probably be using %p for that.
You can figure this out with the help of this equivalence: X[Y] === *(X+Y)
Since *(arr+1) === arr[1], arr+1 === &arr[1]
Similarly, &arr+1 === &((&arr)[1])
What is (&arr)[1]? Well, (&arr)[0] === *&arr === arr,
that is, the 3x3 array itself, so (&arr)[1] is the 3x3 array following that,
and &arr+1 === &((&arr)[1]) is the address of the 3x3 array following &arr ... a pointer to the byte just past the entire array.
Arr+1 gives the next element in an array while &arr +1 gives the address of next array of integers
array + 1 means the array[1] 's address and it costs 3 int memory.
&array + 1 means the address of array[0] add 1;