How do I get a true value when using object_comparison on an empty linked list in my post condition? - eiffel

I have an assignment that requires me to create an empty linked list key: LINKED_LIST [KEY], another linked list data_items_1: LINKED_LIST [DATA1] and a hash table data_items_2: HASH_TABLE [DATA2, KEY] in the constructor. The post condition that my professor put was
object_equality_for_keys: keys.object_comparison
object_equality_for_data_items_1: data_items_1.object_comparison
object_equality_for_data_items_2: data_items_2.object_comparison
When I run the program I get a contract violation. In the debugger it's always pointing to this line of code and I'm not sure why. What is the purpose of this post condition and how do I not violate this contract?

The feature compare_objects of class CONTAINER indicates whether that container uses = (reference comparison) or ~ (value/object comparison, which calls is_equal internally) when comparing items. You can call compare_objects or compare_references to configure individual containers and ensure they work the way you need them to.

Related

Adding a new Entry in a Struct holding a TArray as Member value doesn’t update it’s entries

I am currently working on a Character Customization System where a HUDLayout dynamically create Widgets based on a set of Skins available for the Character Selected. A Skin is represented as a Struct called MaterialInstanceContainer and holds a TArray. Player can mix and match their selection according to the Body Parts they select. In order to achieve the final result, I want to create a TMap<string, MaterialInstanceContainer> so that I can map each BodyParts available for selection with the individual material instance targeting the same BodyPart.
ISSUE: My issue is as follow, when I try to foreach over my collection of Material Instances inside my Container, I do a string comparison and if the output is valid, I can then break my struct to access the Material Instance Array and ADD to it however, at the very end of the process, the length of the array inside Material Container is still at zero.
How can I add a new entry in the array that my Material Container Struct hold?
Thanks!
enter image description here
The issue here is actually pretty straight forward: in Blueprints when you 'Find' a member of Map you are not getting it by-reference, instead you get the copy.
This is exactly what happens at the end of your nested loop: You get a copy, you add item to it, and when another iteration kicks-in the copy gets terminated.
And here on my side it returns exactly the same result as expected:
The fix for that would be easy:
After editing a Copy, you can overwrite the Map member by its copy (via 'Add' node).
But in your case it will be more tricky. You cannot just plug the same BreakStruct/Array node that you just used because it would call whole Find sequence again which creates another copy. Look
If you are confused. This code actually looks like this for Unreal's point of view.
So you have to store the the Struct in local variable first, then perform any operations on it and after everything is done - overwrite the Map member by its locally stored copy. And the result is
Map member gets overwritten every time and everything is as it should be.
Well, almost... For some reason your code is stored in Macro. I think you have to change it to a Function to be able to create local struct variable. But it shouldn't be a problem in this specific case because in your code there is no logic that needs to be done in macro.
Hope, it helps

Test for corrupted list

Suppose I receive a list in a volatile environment, where the tail element is only partially filled with accessible items; further, passing on/deleting/dropping the element is a perfectly adequate solution.
So,
next->A // is unaccessible
next->B // is accessible
if (next->A) // evaluates to true
is there a method to test and pass/delete this list element?
C does not provide a built-in way of testing if a memory location is accessible or not. You cannot check if next->A is available for the same reason that you cannot check if a pointer is "dangling".
A fix to this is to add a level of indirection: make a list of "envelope" objects which are always available. Each envelope holds a pointer to the actual object, along with a flag indicating object's accessibility. This way the provider of the list would be able to manipulate the flag independently of the data object itself, without disturbing the content of the list:

Inserting an item to a linked list - is iteration necessary (C)?

I'm currently studying linked lists for interview prep, would appreciate if anybody could shed some light on this. The following function in C supposedly inserts a new element into the list after a certain Element elem (passed as an argument to the function):
bool insertAfter(Element * elem, int data){
Element * newElem, * curPos = head;
newElem->data = data;
while(curPos){
if(curPos == elem){
newElem->next = curPos->next;
curPos->next = newElem;
return true;
}
curPos = curPos->Next;
}
return false;
}
Although the above is specified in the textbook I am studying from, I tried coming up with a solution that does not use any iteration whatsoever:
bool insertAfter(Element * elem, int data){
Element * newElem;
newElem->next = elem->next
newElem->data = data
elem->next = newElem;
return true;
}
However, as it appears too simplistic, I sense that it may not work, but am not sure why. I need some insights on the technicalities on why this may or may not work, thanks.
Both versions suffer from the error of using newElem as though it were a valid pointer. It is not. It is not initialized to point to valid object.
You can correct that by allocating memory for an object before using:
Element * newElem = malloc(sizeof(*newElem));
The difference between the two versions is that if elem is not accessible from head for some reason or it is NULL, the first version will do nothing to the existing list. The second version does not deal with either of those scenarios. It assumes that elem is in the list and that it is not NULL.
Your solution is pretty much correct. The iteration in the example is almost completely useless.
What the example function is doing is: given an element to insert the new data after, it looks through the list starting with head to find that same element, then inserts the data - doing nothing with head or elem after finding it. Since all the loop does is "find" an element to which you already had a pointer, it essentially did nothing at all and is useless.
The only possible use of this is to constrain the insertion function to only work on this one list beginning with head, globally, throughout your program. This is such a strange design decision that one would likely assume it's a mistake unless given a reason to believe otherwise (dynamic data structures constrained to a single instance are an unusual pattern; more importantly, the whole point of linked lists is O(1) insertion, which the example function breaks by adding this useless loop). head is not needed for any other reason than to enforce this constraint, and if this is desired, it would make more sense to pass it in as a parameter as well so that the function is able to be used on more than one list per-program. (Or, not to perform the check at all: another use of linked lists is that you can pass around and insert after nodes without worrying about the head element.)
As other people have pointed out, you fail to actually allocate newElem, but so does the textbook. Overall, it's a rubbish example; not only did the author make a mistake with allocation, but they don't appear to understand the basic advantages of using linked lists. You should definitely treat this textbook with suspicion.
Your logic will work, because you just need a pointer to a node where you want to insert a node. If you already have such a pointer, no need to iterate and search for the node.
However the search (iteration) would be relevant if do not have in hand the node pointer where you want to insert the new node. Example: suppose the nodes have unique keys and you do not have the node pointer where the key exists and you want to insert after you find the node containing the specific key, then you need to find the correct node pointer and do the insertion (The function should then take in key as the argument).
However in your code (both cases), you have not allocated the memory for the new node. You need to do malloc for the new node and then go on with the insertion.
This will not work because you do not know your newElem. In linked list you have knowledge about a head and each element gives you information where to find the next one:
head -> e1 -> e2 -> ...
So you need to iterate till you will find the element you care about. But you can also iterate with the recursion.

Linked List Implementation Options in C

In implementing a single linked list in C, I think there are three ways :
HEADER IS A POINTER ITSELF.IT POINTS TO THE FIRST NODE OF THE LINKED LIST.
1.Declare the header globally and use function void insert(int) to insert.This should work as header is global.
2.Declare header inside main and use function node*insert(node*) to insert.This should work because of the return involved.
3.Declare header inside main and use function void insert(node**) to insert.
Sometimes the second way works even without the return involved. Why?
Which is the better way?
If the functions involved are recursive as in tree which method is appropriate?
You should encapsulate your data structure in a single object (the head node or a struct that contains it), and then you can have your functions work on that object. This means that you can have more than one linked list in your program (that won't work with a global head node) and you can also pass it around to different functions that want to use it (there's no point having a data structure without being able to use it).
If you have your single object (head node) stored in your program then the insert and delete functions don't need to return anything, as you already have a pointer to the object that represents the linked list.
If the functions involved are recursive as in tree which method is appropriate?
The functions should not be recursive "as in tree". The depth of a tree is O(logn), which means recursion is reasonable in many situations; The size of a linked list is O(n), which means recursion can easily overflow the stack.

Linked List insert in C

I have recently started working with linked lists. To push an element into linked list in the insert(...) function, I saw we always check if(head == NULL) but it occurs only once.
I want to know if there is any way so that we can avoid the unnecessary check always. Please suggest something that would be relevant to most of the linked list operations. One solution I figured out is that writing a new function "add_first_element(....)" so that explicitly we add the first element and then other elements are added in a generic way.
I am looking for a better solution.
A common way is to use a sentinel node. That is, a node that contains no useful data, but merely serves as the placeholder for the one before the first node. This way you don't need to check for null.
For double-linked list, you will need two sentinel nodes to avoid null checking.

Resources