2-D array in C, address generation - c

How do addresses get generated in arrays in C, say how does a [x][y] get to a particular value, i know its not that big a question but just about to actually start coding.

Well it is done depending on your data type of whose array you have considered.
Say for an Integer array, each value holds 4 bytes, thus a row X long will take 4X bytes.
Thus a 2-D matrix of X*Y will be of 4*X*Y Bytes.
Any address say Arry[X][Y] would be
calculated as : (Base Address of Arry)
+ (X * No. of columns) + ( Y // Offset in current row )

2-dimensional arrays in C are rectangular. For example:
int matrix[2][3];
allocates a single block of memory 2*3*sizeof(int) bytes in size. Addressing matrix[0][1] is just a matter of adding 0 * (3 * sizeof(int)) to sizeof(int). Then add that sum to the address at which matrix starts.

A nested array is an array of arrays.
For example, an int[][6] is an array of int[6].
Assuming a 4-byte int, each element in the outer array is 6 * 4 = 24 bytes wide.
Therefore, arr[4] gets the third array in the outer array, or *(arr + 4 * 24).
arr[4] is a normal int[]. arr[4][2] gets the second int in this inner array, or *(arr + 4 * 24 + 2 * 4)

E.g.
char anArray[][13]={"Hello World!","February","John"};
You can visualize it as:
anArray:
H|e|l|l|o| |W|o|r|l|d|!|\0|F|e|b|r|u|a|r|y|\0|\0|\0|\0|\0|J|o|h|n|\0|\0|\0|0|\0
^ ^ ^
0 13 26

Related

Array, pointer and Sizeof relation [duplicate]

This question already has answers here:
Is an array name a pointer?
(8 answers)
How to find the size of an array (from a pointer pointing to the first element array)?
(17 answers)
How Does sizeof(Array) work
(5 answers)
Closed 5 years ago.
I have learned that we can use the address of elements of an array at index i as &A[i] or simply as A+i
and to get the value
A[i] or *(A+i)
where A is an array and i denotes the Index.
Let's say int A[]={1,2,3};
When I use sizeof(*A) I get value 4, now when I use sizeof(A) I must get the size of address value of the first element why I get the size of the whole array as 12.
I am a beginner and confused, please guide.
int A[]={1,2,3};
A is an array and array is not a pointer. when you are printing sizeof(*A) it prints 4 because *A means first element of array which size is 4.
sizeof(A) will results not result in 4 because A is not a pointer. A is an array and array means collection of elements and each elements needs 4 bytes.
A[i] == *(A+i)
sizeof(A[i]) => 4 because A[0] is an integer
sizeof(*A) => 4 because *A means value at starting address and that needs 4 bytes to store
sizeof(A) => 12 bytes, not 4 because A is not a pointer.
sizeof(&A[0]) => 4 bytes because &A[0] yields in address and size of any address will be 4 bytes.
When you call sizeof(A) you get the size of the array as n.m said. But If you initialize your array as this:
int *A = new int[3];
A[0] = 1;
A[1] = 2;
A[2] = 3;
cout << sizeof(A) << endl;
you will get 4.
When I use sizeof(*A) I get value 4
This is nothing but size of first element in the array ie sizeof(*A) is the same as sizeof(*(&A[0])).
now when I use sizeof(A) I must get the size of address value of the first element why I get the size of the whole array as 12
You have declared A as
int A[]={1,2,3};
Now, ask yourself a simple question - What is A ? Never settle with anything other than Array for an answer. In short you get the size of entire array in bytes. Here you have 3 elements which takes 4 bytes each.
Added
I must get the size of address value
That should be sizeof(&A) - which is the size of the address of A - which is usually 8 bytes in many systems.

how to find cell index no. in 2-D array?

in C programming if an 2-D array is given like ( int a[5][3]) and base address and address of particular element (cell ) is also given and have to find index no. of that element(cell) (row and col no.) can we find that? if yes how?
i know the formula of finding address is like this
int a[R][C];
address(a[i][j])=ba+size(C*i+ j);
if ba, R,C,Size and address(a[i][j]) is given... how to find value of i and j?
for finding the value of 2 variable we need 2 equation ..but im not able to find 2nd equation.
The specific address minus the base address gives you the size in bytes, from the base to the specific address.
If you divide that size in bytes with sizeof(ba[0][0]) (or sizeof(int)), you get the number of items.
items / C gives you the first dimension and items % C gives you the second dimension.
Thus:
int ba[R][C];
uintptr_t address = (uintptr_t)&ba[3][2]; // some random item
size_t items = (address - (uintptr_t)ba) / sizeof(ba[0][0]);
size_t i = items / C;
size_t j = items % C;
It is important to carry out the arithmetic with some type that has well-defined behavior, therefore uintptr_t.
If I had done int* address then address - ba would be nonsense, since ba decays into an array pointer of type int(*)[3]. They aren't compatible types.
Use integer division and remainder operators.
If you have the base and a pointer to an element, elt, then there are two things:
In "pure math" terms, you'll have to divide by the size of the elements in the array.
In "C" terms, when you subtract pointers this division is performed for you.
For example:
int a[2];
ptrdiff_t a0 = (ptrdiff_t)&a[0];
ptrdiff_t a1 = (ptrdiff_t)&a[1];
a1 - a0; // likely 4 or 8.
This will likely be 4 or 8 because that's the likely size of int on whatever machine you're using, and because we performed a "pure math" subtraction of two numbers.
But if you let C get involved, it tries to do the math for you:
int a[2];
int * a0 = &a[0];
int * a1 = &a[1];
a1 - a0; // 1
Because C knows the type, and because it's the law, the subtracted numbers get divided by the size of the type automatically, converting the pointer difference into an array-like index or offset.
This is important because it will affect how you do the math.
Now, if you know that the address of elt is base + SIZE * (R * i + j) you can find the answer with integer division (which may be performed automatically for you), subtraction, more integer division, and either modulus or multiply&subtract:
offset or number = elt - base. This will either give you an index (C style) or a numeric (pure math) difference, depending on how you do the computation.
offset = number / SIZE. This will finish the job, if you need it.
i = offset / R. Integer division here - just throw away the remainder.
j = offset - (i*R) OR j = offset % R. Pick what operation you want to use: multiply & subtract, or modulus.

Multidimensional array and addressing

I have an issue with the multidimensional arrays. Maybe the solution is much easier.
int arr[2][2]; //multidimensional array
My simple question is: why the
arr[0][2] and arr[1][0]
or
arr[1][2] and arr[2][0]
are on the same address in my case?
I checked this problem in Linux and Windows environment. And the issue is the same. I have checked tutorials and other sources, but no answer.
The pointer &arr[0][2] is the one-past-the-end pointer of the array arr[0]. This is the same address as that of the first element of the next array, arr[1], which is &arr[1][0], because arrays are laid out contiguously in memory.
arr[2][0] is a bit tricker: arr[2] is not a valid access, but &arr[2] is the one-past-the-end pointer of the array arr. But since that pointer cannot be dereferenced, it doesn't make sense to talk about arr[2][0]. arr doesn't have a third element.
C stores multi-dimensional arrays in what is called row-major order. In that configuration, all the data for a single row is stored in consecutive memory:
arr[2][2] -> r0c0, r0c1, r1c0, r1c2
The alternative would be column-major order, which places the columns consecutively.
Since you have specified the length of the row (number of cols) as 2, it follows that accessing column 2 (the third column) will compute an address that "wraps around" to the next row.
The math looks like:
&(arr[row][col])
= arr # base address
+ row * ncols * sizeof(element)
+ col * sizeof(element)
= arr + sizeof(element) * (row * ncols + col)
In your case, arr[0][2] is arr + (0*2 + 2) * sizeof(int), while arr[1][0] is arr + (1*2 + 0)*sizeof(int).
You can do similar math for the other variations.
Array indexing is identical to pointer arithmetic (actually, the array name first is converted ("decays") to a pointer to the first element before the []-operator is applied):
arr[r][c] <=> *(arr + r * INNER_LENGTH + c)
Your array has two entries per dimension. In C indexes start from 0, so for each dimension valid indexes are 0 and 1 (i.e. total_entries - 1). Which makes three of your expressions suspective in the first place:
arr[0][2] // [outer dimension/index][inner dimension/index]
arr[1][2]
arr[2][0]
We have these cases:
Both indexes are valid: no problem.
Only the address is taken, the element is not accessed and
the outer index is valid and the inner (see below) index equals the length of the inner dimension: comparison and certain address arithmetic is allowed (other constraints apply!).
the outer index equals the length of the outer dimension, and the inner index is 0: The same.
Anything else: the address is invalid and any usage (take address, dereference, etc.) invokes undefined behaviour.
What exactly goes on in memory might become a bit more clear if we use different lengths for the dimensions and have a look how the data is stored:
int arr[3][2];
This is an "array of 3 arrays of 2 int elements". The leftmost dimension is called the "outer", the rightmost the "inner" dimension, because of the memory layout:
arr[0][0] // row 0, column 0
arr[0][1] // row 0, column 1
arr[1][0] // ...
arr[1][1]
arr[2][0]
arr[2][1]
Using the formula above, &arr[0][2] (arr + 0 * 2 + 2) will yield the same as &arr[1][0] (arr + 1 * 2 + 0), etc. Note, however, while the addresses are identical, the first version must not be dereferenced and the compiler may generate incorrect code, etc.
Array indexing in C is similar to adding the value of the index to the address of the first element.
In the multidimensional array that you describe, you have 2 elements on each dimension: 0 and 1. When you introduce a number larger than that, you're referencing an element outside that dimension. Technically, this is an array out of bounds error.
The addresses break down like this:
arr[0][0] - &arr[0] + 0
arr[0][1] - &arr[0] + 1
arr[1][0] - &arr[0] + 2
arr[1][0] - &arr[0] + 3
When you write arr[0][2], you're referencing address &arr[0] + 2, which is the same as arr[1][0]. It all just pointer math, so you can work it out pretty easily once you know how it works.
You can look in your two dimensional array as a long one dimensional array:
[00][01][10][11]
With the pointers arithmetic, another representation of this long one dimensional array is:
[00][01][02][03]
So looking in cell [10] is exactly the same as looking into a cell [20] in pointer arithmetic point of view.

$size, $bits, verilog

What is the difference between $size and $bits operator in verilog.?
if I've variables, [9:0]a,[6:0]b,[31:0]c.
c <= [($size(a)+$size(b)-1]-:$bits(b)];
What will be the output at 'c' from the above expression?
$size() gives the number of bits for a single dimension. $bits() gives the number of bits to completely represent the variable.
For example:
reg [9:0] a;
reg [9:0] b [5:0];
initial begin
$display("a Size ", $size(a));
$display("a Bits ", $bits(a));
$display("b Size ", $size(b));
$display("b Bits ", $bits(b)) ;
end
Gives :
a Size 10
a Bits 10
b Size 6 // Depth of memory
b Bits 60 // Width * Depth
In your case you just have 1 dimensional arrays, not memories or structs so $size() and $bits() would be the same thing.
$size shall return the number of elements in the dimension, which is equivalent to $high - $low + 1. It is relative to the dimension, not only bit counts. If the type is 1D packed array or integral type, it is equal to $bits.
$bits system function returns the number of bits required to hold an expression as a bit stream.
$bits ( [expression|type_identifier] )
It returns 0 when called with a dynamically sized type that is currently empty. It is an error to use the $bits system function directly with a dynamically sized type identifier.
I have no idea about your question, c <= [($size(a)+$size(b)-1]-:$bits(b)];. Is it a valid expression in RHS? Are you talking about the array range expression, [n +: m] or [n -: m] ?

what does this code line do?

Hi I am new to C programming can anyone please tell me what this line of code would do:
i = (sizeof (X) / sizeof (int))
The code actually works with a case statement when it takes a value of bdata and compares it to different cases.
Generally, such a statement is used to calculate the number of elements in an array.
Let's consider an integer array as below:
int a[4];
Now, when sizeof(a) is done it will return 4*4 = 16 as the size. 4 elements and each element is of 4 bytes.
So, when you do sizeof(a) / sizeof(int), you will get 4 which is the length or size of the array.
It computes the number of elements of the array of int named X.
returns the length of the array X
it computes X's volume in memory divided by the size of an integer in your computer(2 bytes or 4 bytes). If i is integer than it is an integer division. If it is float and X has no even volume, it is real division.
int size can change. X depends on implementation. Division result depends on type of i.
All these means, it computes how many ints fit into X.
Besides common practice or personal experience there is no reason to think that this i = (sizeof (X) / sizeof (int)) computes the size of the array X. Most often probably this is the case but in theory X could be of any type, so the given expression would compute the ratio of the sizes of your var X and an int (how much more memory, in bytes, does your X var occupy with respect to an int)
Moreover, if X was a pointer to an array (float* X, the alternate way of declaring arrays in C) this expression would evaluate to 1 on a 32-bit architecture. The pointer would be 4 bytes and the int also 4 bytes => i = sizeof(X) / sizeof(int) (=1)

Resources