Prevent array to writing to nonexistent index - c

I have array of numbers like:
int a[10]={1,1,1,1,1,1,1,1,2,1};
I find position of 2 and then change the value of indexof(2)+4 and -4 to 2 too.
Problem is that indexof(2)+4 does not exist which mean c will overwrite some memory that does not belong to array. How can I stop c to writing into indexes that exceed length of the array?

In C, there is no built-in checking (i.e. that happens without programmer involvement) to ensure array indexing keeps within bounds.
If you want to access (read or write) a[i] then you need to write code check that i is a valid index before doing so, and don't access a[i] if i is invalid. That means ensuring the value is between 0 and n-1, where n is known to be the number of elements in the array.
There are various options to obtain or set the value of n. Each have limits on applicability.

You can use sizeof() operator to get the size of the array. Using it you can check whether the value indexof(2)+4 is greater than the array size before changing the value.

Related

Was it possible to access the array element of its own size?

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.

How to re-arrange elements of Array after Deleting

Recently I was reading a Programming book and found this question:
I have an array :
array = [2,3,6,7,8,9,33,22];
Now, Suppose I have deleted the element at 4th position i.e. 8 .
Now I have to rearrange the array as:
Newarray = [2,3,6,7,9,33,22];
How Can I do this. And I have to also minimize the complexity.
Edit I have no choice to make another copy of it.I have to only modify it.
You can "remove" a value from an array by simply copy over the element by the next elements, that's easy to do with memmove:
int array[8] = {2,3,6,7,8,9,33,22};
memmove(&array[4], &array[5], sizeof(int) * 3);
The resulting array will be {2,3,6,7,9,33,22,22}.
And from that you can see the big problem with attempting to "remove" an element from a compile-time array: You can't!
You can overwrite the element, but the size of the array is fixed at time of compilation and can't actually be changed at run-time.
One common solution is to keep track of the actual number of valid elements in the array manually, and make sure you update that size as you add or remove elements. Either that or set unused elements to a value that's not going to be used otherwise (for example if your array can only contain positive numbers, then you could set unused elements to -1 and check for that).
If you don't want to use a library function (why not?) then loop and set e.g.
array[4] = array[5];
array[5] = array[6];
and so on.
Do this, just use these two functions and it will work fine
index=4;//You wanted to delete it from the array.
memcpy(newarray,array,sizeof(array));
memmove(&newarray[index], &newarray[index + 1], sizeof(newarray)-1);
now the newarray contains your exact replica without the character that you wished to remove
You can simply displace each element from the delIdx(deletion index) one step forward.
for(int i=delIdx; i<(arr_size-1);i++)
{
arr[i]= arr[i+1];
}
If required you can either set the last element to a non-attainable value or decrease the size of the array.

Number sequences length, element first and last indexes in array

Im beginner in programming. My question is how to count number sequences in input array? For example:
input array = [0,0,1,1,1,1,1,1,0,1,0,1,1,1]
output integer = 3 (count one-sequences)
And how to calculate number sequences first and last indexes in input array? For example:
input array = [0,0,1,1,1,1,1,1,0,1,0,1,1,1]
output array = [3-8,10-10,12-14] (one first and last place in a sequence)
I tried to solve this problem in C with arrays. Thank you!
Your task is a good exercise to familiarize you with the 0-based array indexes used in C, iterating arrays, and adjusting the array indexes to 1-based when the output requires.
Taking the first two together, 0-based arrays in C, and iterating over the elements, you must first determine how many elements are in your array. This is something that gives new C programmers trouble. The reason being is for general arrays (as opposed to null-terminated strings), you must either know the number of elements in the array, or determine the number of elements within the scope where the array was declared.
What does that mean? It means, the only time you can use the sizeof operator to determine the size of an array is inside the same scope (i.e. inside the same block of code {...} where the array is declared. If the array is passed to a function, the parameter passing the array is converted (you may see it referred to as decays) to a pointer. When that occurs, the sizeof operator simply returns the size of a pointer (generally 8-bytes on x86_64 and 4-bytes on x86), not the size of the array.
So now you know the first part of your task. (1) declare the array; and (2) save the size of the array to use in iterating over the elements. The first you can do with int array[] = {0,0,1,1,1,1,1,1,0,1,0,1,1,1}; and the second with sizeof array;
Your next job is to iterate over each element in the array and test whether it is '0' or '1' and respond appropriately. To iterate over each element in the array (as opposed to a string), you will typically use a for loop coupled with an index variable ( 'i' below) that will allow you to access each element of the array. You may have something similar to:
size_t i = 0;
...
for (i = 0; i< sizeof array; i++) {
... /* elements accessed as array[i] */
}
(note: you are free to use int as the type for 'i' as well, but for your choice of type, you generally want to ask can 'i' ever be negative here? If not, a choice of a type that handles only positive number will help the compiler warn if you are misusing the variable later in your code)
To build the complete logic you will need to test for all changes from '0' to '1' you may have to use nested if ... else ... statements. (You may have to check if you are dealing with array[0] specifically as part of your test logic) You have 2 tasks here. (1) determine if the last element was '0' and the current element '1', then update your sequence_count++; and (2) test if the current element is '1', then store the adjusted index in a second array and update the count or index for the second array so you can keep track of where to store the next adjusted index value. I will let you work on the test logic and will help if you get stuck.
Finally, you need only print out your final sequence_count and then iterate over your second array (where you stored the adjusted index values for each time array was '1'.
This will get you started. Edit your question and add your current code when you get stuck and people can help further.

C programming: Delete specific value stored in Array

Let us consider an array (say, int a[25];).
Later with the help of some loop I start storing the user input in this array.
At some point of time if user choose to delete the value he just entered from the array.
How can I do that for the user of my program.
I can make that 0, but 0 is also a value he could enter; so I simply want to make it NULL or with some garbage value, as it was when I initialized the array.
You can't delete an element from an array. In C arrays are stored as a contiguous block of memory, so you can't just remove an element. You can use any of the following options:
Use some unused value like -1 to mark the element as deleted.
Use separate array to keep track of deleted elements.
Use linked list to store your elements(Recommend option).
You can't.
If you define
int a[25];
then a consists of 25 int elements. Each element, once you assign a value to it, retains that value until it's reassigned, or until the array ceases to exist. You can't "delete" a value from an array. There is no special NULL value for integers as there is for pointers.
You can pick a special value that denotes an "empty" element (perhaps INT_MIN) -- but then you won't be able to store that value as data. Or you can use another data structure, perhaps an array of bool, to keep track of whether the current value of each element of a is valid or not.

bsearch and searching range?

bsearch is pretty good for direct search, but what should I use if I need for example search range?
update
for example if i want to find range of values between a and b ( a >= x < b ).
update
range values can be not equal.
so if i have array(10,20,30) and i'm trying to find "15" i want to get address (pointer) to minimal range that is closest, in this example this is range (10,20)
One of the parameters bsearch takes is the number of elements to search. So instead of, for example, 100, make it search in 42 ...
bsearch("foo", data, /*100*/42, sizeof *data, cmpfx);
After the update
What I'd do is a manual (meaning I'd write the code) binary search.
The idea is to compare the middle element of the (remaining) array to both the lower and upper limit. If it's smaller then the lower limit search again in the small half; if it's larger than the upper limit search again in the big half; otherwise you've found an element in range.
After the 2nd update
You want to return a pair of pointers?
You have to wrap them inside a struct, or pass the addresses of the pointers to the functions ... or something.
But now you have a simpler search: search until you find the value (and return a 0-length range) or until you are about to fail. The range is between the array value you last looked at and, depending on exactly how you got to the fail situation, the value to one of the sides or EMPTY if you're at the end of the array.
The bsearch() function is designed to find a single element matching some condition. According to the man page:
RETURN VALUE
The bsearch() function returns a pointer to a matching member of the
array, or NULL if no match is found. If there are multiple elements
that match the key, the element returned is unspecified.
The key here is that if there are multiple elements that match the key, the element returned is unspecified. So you don't know if the element you get is the first, last, or somewhere in the middle of the range.
If you can change your requirements so that you're looking for elements in the array between A and B, and you can guarantee that there is exactly one A and exactly one B in the array, then you could first search for A then search for B.
start = bsearch(A, array, N, sizeof(*array), compare);
end = bsearch(B, array, N, sizeof(*array), compare);
You'll probably have to write your own function to do exactly what you're wanting.

Resources