In the given code, there is a method that
for(i = pos - 1 ; i < size -1 ; i++)
{
a[i] = a[i+1] ;
}
but suppose the size is 4 and I want to delete the 4th position value of the array.
In this scenerio I am not able to understand how this code will work.
It seems you do not quite understand how arrays are in C.
In C, an array is a continuous sequence of items of the same type and therefore same size.
The system will allocate space for the array initially.
For example when you say int a[4] and run your function, a is of type "array of int", each entry is type of 'int'.
Mostly, an int value needs 4 bytes of space. And the [4] means space for four ints will be allocated. That is, it will allocate 4*4=16 bytes in your memory.
For example, down here is the spaces allocated by a:
01010101 first byte (start of a[0])
01111110 second byte
00101001 third byte
00000111 fourth byte
01100000 fifth byte (start of a[1])
.....
.....
.....
01010101 16th byte
While it is just allocated, the bytes value is unknown. You can initialize or assign value to it.
Okay, then when you use a to do something, you can say a[1] to access the int represented by the 4 bytes ranging from the 5th byte to the 8th byte.
What will happen if you say a[10]?
The space is not allocated by your program! Accessing it is an error. But only if you are lucky maybe an error tip window showing "Access Violation at memory 0x6463a80 (the number is just example)" or you get a value unknown without a noticeable warning and that would be worse!
From your question, I know that you want to say,
"Oh gosh, I originally have int a[4], but later in the code, I want to shrink it to something like int a[3]!"
The solution is: just ignore a[3], view it as it does not exist! Never use a[3] then that's okay!
If you want to have a full access of operations like "Add" "insert" "Remove" etc. Array is not suitable. Consider C++. It has std library, and there is Vector type. It's not array, it works different from this. Search Google or chat me if u want to know.
You may be not completely understand what I am saying here but please feel free to ask. I'm almost on the same boat with you and I am willing to teach & help you.
Related
i only would know how to store value in the last position of the array, with the code below:
int main(int argc, char *argv[]){
int x[2][2];
int i, j;
x[2][0] = 1;
printf("%d", x[2][2]);
}
Thanks!
The last element in your matrix is in x[1][1]; just put in this position. Your vector has only four positions indexed starting in 0 going to 1 twice (for each dimension); that is, neither x[2][0] nor x[2][2] is valid — they access out of the bounds of the array.
The first element of an array in C is numbered as 0, and when creating an array, the size inputted will represent the number of elements in the said array. Hence, the first element of an array of 2 would be labelled as 0 and the second as 1, the third(2) not being allocated.
So, for example, making an array of 4 variables:
int i[4]
Would allocate four ints int memory,
i[0]
i[1]
i[2]
i[3]
these being the valid spots of the array. Of course this applies to 2D arrays like yours.
If you wish a 3-large array(Like I suppose from your use of the array element zero and two), you simply need to, as you probably understood, declare an array with a size of [3].
Keep in mind accessing invalid spots in an array might not cause a crash of your program if it had allocated some memory at the emplacement it tried to access, sometimes yielding to funny results caused by these unexpected values.
Hope this helps.
I'm a bit confused about a thing :
If I have an array of structs: table whith a length of X and I want to access the last element of it: table[X] or table[X-1]. If it's table[X-1], what table[X] contains ?
The indexing of array in C starts with zero, i.e. the first element will be in table[0], the second in table[1], the third in table[2] ... and the last on in table[X-1].
table[X] is outside of the arrays bounds. C does not have bounds checking, so compiler allows accessing it, but this is an undefined behaviour, i.e. you will never know what happens. Reading it can give back memory garbage or can lead to an OS exception like segmentation fault.
The answer is the same for any kind of array. If you have one with the size
X :
int a[5];
struct my_struct ms[10];
...
you specify the amount of elements in that array. Because the 1st element is element 0, the last element is always X - 1.
If you try to access the element a[X] you will get undefined behavior.
Structs work in memory the same way that an integer or some other basic data type would in this instances. Your array would just be separated by sizeof(struct) instead of sizeof(the basic data type).
It'd still start at 0, and end at X - 1. The type of arrays usually just really defined 2 things:
The amount of bytes per index, and how to treat the data.
Picture an array of size 3 with structs that contain 5 bytes of data. Your array would just be set as follows:
-----|-----|-----|????|
s1 |s2 |s3 |????|
Just because it exists, doesn't mean our program knows what it is. the 4th [3] index (????) would be an index out of bounds of our array. It is possible however you could get some meaningful value here, but very unlikely. Most of the time it will either be garbage, or cause an error.
Arrays in C use zero indexing, meaning they start with 0 and end with n-1. Not to be confused with array declarations, where you write the size expressed in number of items. The syntax for accessing an array and declaring one looks similar, which is why this can be confusing for beginners.
Example:
int main (void)
{
int array[5]; // allocate an array with 5 elements
array[0] = 0; // access first element
array[4] = 0; // access last element (index 4)
array[5] = 0; // BAD, accessing the array out of bounds: index 5 gives item number 6
}
And this is why the canonical way to write for loops in C is this:
for(int i=0; i<n; i++)
where n is the size of the array, and the iterator i will have the values from 0 to n-1.
Would running this code occupy about 4_000_000 bytes of memory?
my uint32 #array;
#array[1_000_000] = 1;
If you assign element 1_000_000 and each element is 4 bytes, that would be 4_000_004 bytes of memory. So strictly speaking, the answer is "No" :-)
But less pedantically: native arrays are guaranteed to be laid out consecutively in memory, so such an assignment would at least allocate a single block of 4 x 1_000_001 = 4_000_004 bytes of memory. As Christoph stated in his comment, if you want to make sure it is all it will ever allocate, you need to make it a shaped native array. You will get upper bounds checks as a bonus as well.
Can we access the mth array element, if it has m elements?
I mean that, if the array has 7 elements, was it ever possible to store any value in array[7]?
But the array indexes start from 0 and end with 6, when length is is 7.
No, accessing the element beyond the array bound is undefined behaviour. Taking address of the element 1 beyond last array element is well defined.
To understand the implications, consider reading How dangerous is it to access an array out of bounds?
No, You are only allowed to access elements with indexes from 0 up to size-1. Anything outside of that range causes undefined behavior. If the index was near the range, most probably you read your own program's memory. If the index was largely out of range, most probably your program will be killed by the operating system.
You answer your own question -
was it ever possible to store any value in array[7]? But the array indexes start from 0 and end with 6, when length is is 7
As you see for array of length 7 , possible indexes are from 0 to 6. Array is allocated that much memory on stack. If you try to access array[7] then you would be accessing memory past the array which is un-initialized and un-authorized and will cause undefined behaviour.
Never try to access out-of-bounds array elements. It has undefined behavior.
Though, if you are a damn crazy man, you may try something like this:
int ar[7];
int tmp = ar[7];
ar[7] = 8;
std::cout << ar[7] << std::endl; // the output is 8, as you can guess
ar[7] = tmp;
If you are lucky enough, this will not cause any error, since you put the initial value of ar[7] back. If you don't, MSVS, in the end of the function, will generate a runtime error with the message:Stack around the variable 'ar' was corruptedDon't know about other compilers.
Given char foo[4], memory will be allocated like this:
foo+0 foo+1 foo+2 foo+3 foo+4
| | | | |
|first |second|third |fourth|
with the first element nestled between foo+0 and foo+1, the second between foo+1, and foo+2, the third between foo+2 and foo+3, and the fourth between foo+3 and foo+4. The address foo+4 is a perfectly fine address, but the fourth element immediately precedes it (likewise the first element is immediately before foo+1, the second before foo+2, and the third before foo+3.
Most code identifies elements by their starting address, but sometimes it may be useful to have code which operates upon the element immediately preceding a pointer. For example, if a software-stack pointer points at the next location where an item should be written, then popping the stack should return the item before the address given by that pointer. If the stack used byte-sized objects and was initialized to foo, then after four single-byte items have been pushed the pointer would be equal to foo+4, indicating that the next item to be popped should be the fourth one.
Can someone explain what would happen? Is it really necessary to start at index 0 instead of 1 (which would be easier for me)?
You can do whatever you want, as long as your array subscript is strictly less than the size of the array.
Example:
int a[100];
a[1] = 2; // fine, 1 < 100
What happens if I don't use zero-based array in C
Well, you can't. C arrays are zero based, by definition, by standard.
Is it really necessary to start at 0?
Well, this is no rule to prevent you from leaving index 0 unused, but then, you'll almost certainly not get the desired result.
Using non-zero based arrays in C is possible, but not recommended. Here is how you would allocate a 1-based array of 100 integers:
int * a = ((int*)malloc(100*sizeof(int)))-1;
The -1 moves the start of the pointer back one from the start of the array, making the first valid index 1. So this array will have valid indices from 1 to 100 inclusive.
a[1] = 10; /* Fine */
a[100] = 7; /* Also fine */
a[0] = 5; /* Error */
The reason why this isn't recommended is that everything else in C assumes that pointers to blocks of memory point to the first element of interest, not one before that. For example, the array above won't work with memcpy unless you add 1 to the pointer when passing it in every time.