I'm reading a lecture slide in my data structures class for arrays, but there is something that sort of confused me.
The example is in an array called x, defined as follows:
1-dimensional array x = [a, b, c, d]
location(x[i]) = start + i
I'm not really understanding this, so could somebody explain this?
start is a variable, which holds address to the array. Since a pointer in 32-bit system has 4 bytes, it will occupy these four bytes. So if you want 4-byte array, you will actually need 8 bytes of memory: 4 for the array and another 4 for pointer to the first element of this array.
Related
This question already has answers here:
Why does the indexing start with zero in 'C'?
(16 answers)
Closed 3 years ago.
Not really a code problem but a doubt, why do arrays on C and C++ start on 0? Does it have anything to do with some internal process?
int array[4]={1,2,3,4};
cout<<array[0];
cout<<array[1];
cout<<array[2];
cout<<array[3]; ///This prints 1234
But why that instead of
int array[4]={1,2,3,4};
cout<<array[1]; //as the first element
cout<<array[2];
cout<<array[3];
cout<<array[4];
?
Because the notation does pointer arithmetic. array[0] actually means the location of the array plus the size of 0 elements.
As always in C, you're working close to the hardware.
Consider int arr[i] elements.
arr[i] is interpreted as *(arr + i). Now, arr is the address of the array or address of the 0th index element of the array. So, address of next element in the array is arr + 1 (because elements in the array are stored in consecutive memory locations).
So if you do *(arr+0) it gives the starting memory location of the array.
and *(arr+1) gives next memory location. so this i i.e 0,1,..etc can use like offset.
As #ravnsgaard said in C, you're working close to the hardware.
On my MS VS 2015 compiler, the sizeof int is 4 (bytes). But the sizeof vector<int> is 16. As far as I know, a vector is like an empty box when it's not initialized yet, so why is it 16? And why 16 and not another number?
Furthermore, if we have vector<int> v(25); and then initialize it with int numbers, then still the size of v is 16 although it has 25 int numbers! The size of each int is 4 so the sizeof v should then be 25*4 bytes seemingly but in effect, it is still 16! Why?
The size of each int is 4 so the sizeof v should then be 25*4 bytes seemingly but in effect, it is still 16! Why?
You're confusing sizeof(std::vector) and std::vector::size(), the former will return the size of vector itself, not including the size of elements it holds. The latter will return the count of the elements, you can get all their size by std::vector::size() * sizeof(int).
so why is it 16? And why 16 and not another number?
What is sizeof(std::vector) depends on implmentation, mostly implemented with three pointers. For some cases (such as debug mode) the size might increase for the convenience.
std::vector is typically a structure which contains two elements: pointer (array) of its elements and size of the array (number of elements).
As size is sizeof(void *) and the pointer is also sizeof(void *), the size of the structure is 2*sizeof(void *) which is 16.
The number of elements has nothing to do with the size as the elements are allocated on the heap.
EDIT: As M.M mentioned, the implementation could be different, like the pointer, start, end, allocatedSize. So in 32-bit environment that should be 3*sizeof(size_t)+sizeof(void *) which might be the case here. Even the original could work with start hardcoded to 0 and allocatedSize computed by masking end so really dependent on implementation. But the point remains the same.
sizeof is evaluated at compile time, so it only counts the size of the variables declared in the class, which probably includes a couple of counters and a pointer. It's what the pointer points to that varies with the size, but the compiler doesn't know about that.
The size can be explained using pointers which can be: 1) begin of vector 2) end of vector and 3) vector's capacity. So it would be more of like implementation dependent and it will change for different implementation.
You seem to be mixing "array" with "vector". If you have a local array, sizeof will provide the size of the array indeed. However, vector is not an array. It is a class, a container from STL guaranteeing that the memory contents are located within a single block of memory (that may get relocated, if vector grows).
Now, if you take a look at the std::vector implementation, you'll notice it contains fields (at least in MSVC 14.0):
size_type _Count = 0;
typename _Alloc_types::_Alty _Alval; // allocator object (from base)
_Mylast
_Myfirst
That could sum up to 16 bytes under your implementation (note: experience may vary).
int (*ptr)[3]=new int [1][3];
I understand that int (*ptr)[3] creates a pointer to a 3-element integer-holding array.
I understand that new int [1][3] dynamically allocates some memory of size 1 row x 3 col x 4 bytes (32-bit machine) = 12 bytes.
I also understand that ptr [0] = &ptr [0] in this case.
The total memory allocated here is 3 * 12 bytes. Why?
Why is the 3 on the LHS dependent on the 3 on the RHS? If we use 3 on the RHS, we have to use 3 on the LHS. I cannot use 2 or 4.
Maybe it's a trivial logic, but I don't seem to find good literature on this.
First, the total memory allocated is not 3*12 bytes. It's
3*1*sizeof(int) + k bytes, where k is unspecified (but in
most implementations, will be 0 when allocating arrays of
int).
Second, the two 3 must be equal because they are part of the
type. On the left, the type is "pointer to 3 int". On the
right, you are allocating an "array of 1 array of 3 int";
because of the semantics of array new, the type of the
expression is point to array of 3 int (and any information
concerning whether it was int[1][3] or int[2][3] or whatever
has been lost). C++ uses static type checking (for the most
part), so the compiler must know all parts of the type at
compile time.
Given the information you have provided so far, I can only answer the second part of your question:
Why is the 3 on the LHS dependent on the 3 on the RHS?
int (*ptr)[3] // creates a pointer to an array of 3 ints
that means your variable ptr should point to an array of array of length threes only and when you are writing new int [1][3], you are essentially creating an array of length threes with one row(2-D array) only. Similarly new int [2][3] would give you an array of threes with two rows.(2-D array) That's why both of the threes are dependent on each other.
Here is the problem program:
#include <stdio.h>
int main()
{
int apricot[2][3][5];
int (*r)[5]=apricot[0];
int *t=apricot[0][0];
printf("%p\n%p\n%p\n%p\n",r,r+1,t,t+1);
}
The output of it is:
# ./a.out
0xbfa44000
0xbfa44014
0xbfa44000
0xbfa44004
I think t's dimension's value should be 5 because t is the last dimension,and the fact is matched(0xbfa44004-0xbfa44000+1=5)
But the r's dimension's value is 0xbfa44014-0xbfa44000+1=21,I think it should be 3*5=15,because 3 and 5 are the last two dimensions,then why the difference is 21?
r is a pointer to an array of 5 ints.
Assuming 1 int is 4 bytes on your system (from t and t+1), then "stepping" that pointer by 1 (r+1) means an increase in 5*4 = 20 bytes. Which is what you get here.
You get tricked by the C syntax. r is an array pointer to an array of int, t is a plain int pointer. When doing any kind of pointer arithmetic, you do it in the unit pointed at.
Thus t+1 means the address of t + the size of one pointed-at object. Since t points at int and int is 4 bytes on your system, you get an address 4 bytes from t.
The same rule applies to r. It is a pointer to an array of 5 int. When you do pointer arithmetic on it by r+1, you get the size of the pointed-at object, which has size 5*sizeof(int), which happens to be 20 bytes on your computer. So therefore r+1 gives you an address 20 bytes (==14 hex) from r.
I want to define an integer variable in C/C++ such that my integer can store 10 bytes of data or may be a x bytes of data as defined by me in the program.
for now..!
I tried the
int *ptr;
ptr = (int *)malloc(10);
code. Now if I'm finding the sizeof ptr, it is showing as 4 and not 10. Why?
C and C++ compilers implement several sizes of integer (typically 1, 2, 4, and 8 bytes {8, 16, 32, and 64 bits}), but without some helper code to preform arithmetic operations you can't really make arbitrary sized integers.
The declarations you did:
int *ptr;
ptr = (int *)malloc(10);
Made what is probably a broken array of integers. Broken because unless you are on a system where (10 % sizeof(int) ) == 0) then you have extra bytes at the end which can't be used to store an entire integer.
There are several big number Class libraries you should be able to locate for C++ which do implement many of the operations you may want preform on your 10 byte (80 bit) integers. With C you would have to do operation as function calls because it lacks operator overloading.
Your sizeof(ptr) evaluated to 4 because you are using a machine that uses 4 byte pointers (a 32 bit system). sizeof tells you nothing about the size of the data that a pointer points to. The only place where this should get tricky is when you use sizeof on an array's name which is different from using it on a pointer. I mention this because arrays names and pointers share so many similarities.
Because on you machine, size of a pointer is 4 byte. Please note that type of the variable ptr is int *. You cannot get complete allocated size by sizeof operator if you malloc or new the memory, because sizeof is a compile time operator, meaning that at compile time the value is evaluated.
It is showing 4 bytes because a pointer on your platform is 4 bytes. The block of memory the pointer addresses may be of any arbitrary size, in your case it is 10 bytes. You need to create a data structure if you need to track that:
struct VariableInteger
{
int *ptr;
size_t size;
};
Also, using an int type for your ptr variable doesn't mean the language will allow you to do arithmetic operations on anything of a size different than the size of int on your platform.
Because the size of the pointer is 4. Try something like:
typedef struct
{
int a[10];
} big_int_t;
big_int_t x;
printf("%d\n", sizeof(x));
Note also that an int is typically not 1 byte in size, so this will probably print 20 or 40, depending on your platform.
Integers in C++ are of a fixed size. Do you mean an array of integers? As for sizeof, the way you are using it, it tells you that your pointer is four bytes in size. It doesn't tell you the size of a dynamically allocated block.
Few or no compilers support 10-byte integer arithmetic. If you want to use integers bigger than the values specified in <limits.h>, you'll need to either find a library with support for big integers or make your own class which defines the mathematical operators.
I believe what you're looking for is known as "Arbitrary-precision arithmetic". It allows you to have numbers of any size and any number of decimals. Instead of using fixed-size assembly level math functions, these libraries are coded to do math how one would do them on paper.
Here's a link to a list of arbitrary-precision arithmetic libraries in a few different languages, compliments of Wikipedia: link.