Why can't I create a pointer to a TTreeNode in a TTreeView - c++builder-10.4-sydney

Using C++ Builder in Rad Studio 10.4
Why can't I create a pointer to a TTreeNode?
I have a TTreeView called BookmarksTree, and I want to loop through all of its nodes. When I try and compile this:
TTreeNode *Node;
Node = BookmarksTree->Items[1];
I get a compiler error:
assigning to 'Vcl::Comctrls::TTreeNode *' from incompatible type 'Vcl::Comctrls::TTreeNodes'
According to Vcl.ComCtrls.TCustomTreeView.Items, I should be able to use
MyTreeNode = TreeView1->Items[[1]];
Has anyone any idea what's wrong here?

BookmarksTree->Items is a pointer to a single TTreeNodes object. You are trying to perform pointer arithmetic to access a node as if the Items were an array of TTreeNode* pointers, which is simply not the case.
You need to use the TTreeNodes::Item[] sub-property instead, eg:
int count = BookmarksTree->Items->Count;
for(int i = 0; i < count; ++i)
{
TTreeNode *Node = BookmarksTree->Items->Item[i];
...
}
Alternatively, you can use the TTreeNodes::operator[], but that requires you to dereference the TTreeNodes* pointer first, eg:
int count = BookmarksTree->Items->Count;
for(int i = 0; i < count; ++i)
{
TTreeNode *Node = (*(BookmarksTree->Items))[i];
...
}
Alternatively, in the Clang-based compilers only, you can use C++ iterators, per C++ Iterator Support for Delphi Enumerable Types and Containers, eg:
auto iter = std::begin(BookmarksTree->Items);
auto end = std::end(BookmarksTree->Items);
while (iter != end)
{
TTreeNode *Node = *iter++;
...
}
Or a range-for loop (which uses iterators internally):
for(TTreeNode *Node : BookmarksTree->Items)
{
...
}

Related

Bad address error when comparing Strings within BPF

I have an example program I am running here to see if the substring matches the string and then print them out. So far, I am having trouble running the program due to a bad address. I am wondering if there is a way to fix this problem? I have attached the entire code but my problem is mostly related to isSubstring.
#include <uapi/linux/bpf.h>
#define ARRAYSIZE 64
struct data_t {
char buf[ARRAYSIZE];
};
BPF_ARRAY(lookupTable, struct data_t, ARRAYSIZE);
//char name[20];
//find substring in a string
static bool isSubstring(struct data_t stringVal)
{
char substring[] = "New York";
int M = sizeof(substring);
int N = sizeof(stringVal.buf) - 1;
/* A loop to slide pat[] one by one */
for (int i = 0; i <= N - M; i++) {
int j;
/* For current index i, check for
pattern match */
for (j = 0; j < M; j++)
if (stringVal.buf[i + j] != substring[j])
break;
if (j == M)
return true;
}
return false;
}
int Test(void *ctx)
{
#pragma clang loop unroll(full)
for (int i = 0; i < ARRAYSIZE; i++) {
int k = i;
struct data_t *line = lookupTable.lookup(&k);
if (line) {
// bpf_trace_printk("%s\n", key->buf);
if (isSubstring(*line)) {
bpf_trace_printk("%s\n", line->buf);
}
}
}
return 0;
}
My python code here:
import ctypes
from bcc import BPF
b = BPF(src_file="hello.c")
lookupTable = b["lookupTable"]
#add hello.csv to the lookupTable array
f = open("hello.csv","r")
contents = f.readlines()
for i in range(0,len(contents)):
string = contents[i].encode('utf-8')
print(len(string))
lookupTable[ctypes.c_int(i)] = ctypes.create_string_buffer(string, len(string))
f.close()
b.attach_kprobe(event=b.get_syscall_fnname("clone"), fn_name="Test")
b.trace_print()
Edit: Forgot to add the error: It's really long and can be found here: https://pastebin.com/a7E9L230
I think the most interesting part of the error is near the bottom where it mentions:
The sequence of 8193 jumps is too complex.
And a little bit farther down mentions: Bad Address.
The verifier checks all branches in your program. Each time it sees a jump instruction, it pushes the new branch to its “stack of branches to check”. This stack has a limit (BPF_COMPLEXITY_LIMIT_JMP_SEQ, currently 8192) that you are hitting, as the verifier tells you. “Bad Address” is just the translation of kernel's errno value which is set to -EFAULT in that case.
Not sure how to fix it though, you could try:
With smaller strings, or
On a 5.3+ kernel (which supports bounded loops): without unrolling the loop with clang (I don't know if it would help).

CS50 pset 3: Tideman sort_pairs function

I need some assistance in understanding the logic behind this function. This is my current sort_pairs function in Tideman:
// Sort pairs in decreasing order by the strength of victory
void sort_pairs(void)
{
qsort(pairs, pair_count, sizeof(pair), compare);
return;
}
// Function for sort_pairs
int compare(const void *a, const void *b)
{
const pair *p1 = (const pair *) a;
const pair *p2 = (const pair *) b;
if (p1->winner < p2->winner)
{
return -1;
}
else if (p1->winner > p2->winner)
{
return 1;
}
else
{
return 0;
}
}
This does not clear check50 and I looked online to find how to approach this problem. It seems that most functions compare the values from the preferences array instead (eg preferences[pairs[i].winner][pairs[i].loser]) . My previous functions vote, record_preferences, and add_pairs all clear check50. I have not advanced beyond sort_pairs yet.
Why can't I compare the strength of victory directly from the pairs array instead since I already have the data stored there?
You don't need to make this so complex, you can use your own sorting here. Let's try a simple insertion sort-
void sort_pairs()
{
pair temp;
for (int i = 1, j; i < pair_count; i++)
{
temp = pairs[i];
j = i - 1;
for (; j >= 0 && preferences[pairs[j].winner][pairs[j].loser] < preferences[temp.winner][temp.loser]; j--)
{
pairs[j + 1] = pairs[j];
}
pairs[j + 1] = temp;
}
}
The pair struct looks like-
typedef struct
{
int winner;
int loser;
}
pair;
Explanation:-
We go through each pair of elements inside the pairs array - starting at 1 since I'm going to compare with the previous element (j = i - 1)
Now we check all the previous elements from the current element and compare them with the key - preferences[pairs[INDEX].winner][pairs[INDEX].loser]
This is the key you should be sorting by. preferences[WINNER_ID][LOSER_ID] means the amount of people that prefer WINNER_ID over LOSER_ID.
And that's pretty much it!, it's simply a insertion sort but the key is the important part.

Linked List Parameterized constructor

I tried to do a Parameterized constructor for a linked list my program is about to implement a queue by using a liked list so i want to do a parameterized constructor like Queue(int value , int size) and it dose not run or doing a list
this is my code for this problem
Queue(int value,int _size)
{
for(int i = 0; i < _size; ++i)
{
Node* temp = new Node;
temp->data = value;
temp->next = nullptr;
if(head == nullptr)
{
head = tail = temp;
}
else
{
tail->next = temp;
tail = temp;
}
}
}
i expected that the result is to fill the lest by value times size like if i run this function Queue x(20,3) the linked list should be
20 20 20
Since that this is a constructor, The head and tail are not properly initialized to use them. I would suggest adding head = tail = nullptr just before the loop and see what happens.
Follow this code after your node creation. I hope this will work. And do use i++ instead of ++i, as the later will make the loop for size-1 times.
if(head == NULL)
head = temp;
else{
Node *x;
x= head;
while(x->next != NULL)
x = x->next;
x->next = temp;
}

Atomically setting a variable without comparing first

I've been reading up on and experimenting with atomic memory access for synchronization, mainly for educational purposes. Specifically, I'm looking at Mac OS X's OSAtomic* family of functions. Here's what I don't understand: Why is there no way to atomically set a variable instead of modifying it (adding, incrementing, etc.)? OSAtomicCompareAndSwap* is as close as it gets -- but only the swap is atomic, not the whole function itself. This leads to code such as the following not working:
const int N = 100000;
void* threadFunc(void *data) {
int *num = (int *)data;
// Wait for main thread to start us so all spawned threads start
// at the same time.
while (0 == num) { }
for (int i = 0; i < N; ++i) {
OSAtomicCompareAndSwapInt(*num, *num+1, num);
}
}
// called from main thread
void test() {
int num = 0;
pthread_t threads[5];
for (int i = 0; i < 5; ++i) {
pthread_create(&threads[i], NULL, threadFunc, &num);
}
num = 1;
for (int i = 0; i < 5; ++i) {
pthread_join(threads[i], NULL);
}
printf("final value: %d\n", num);
}
When run, this example would ideally produce 500,001 as the final value. However, it doesn't; even when the comparison in OSAtomicCompareAndSwapInt in thread X succeeds, another thread Y can come in set the variable first before X has a chance to change it.
I am aware that in this trivial example I could (and should!) simply use OSAtomicAdd32, in which case the code works. But, what if, for example, I wanted to set a pointer atomically so it points to a new object that another thread can then work with?
I've looked at other APIs, and they seem to be missing this feature as well, which leads me to believe that there is a good reason for it and my confusion is just based on lack of knowledge. If somebody could enlighten me, I'd appreciate it.
I think that you have to check the OSAtomicCompareAndSwapInt result to guarantee that the int was actually set.

is there any way to use .indexOf to search a javascript array in mirth?

I am trying to find a string in a javascript array in the transformer of a mirth channel. Mirth throws an error when I try to use indexOf function. My understanding is that indexOf is something that browsers add in, rather than a native part of the javascript language itself. ( How do I check if an array includes an object in JavaScript? )
So is array.indexOf just not supported in Mirth? Is there any way to use .indexOf in Mirth? Maybe an alternate syntax? Or do I need to just loop thru the array to search?
This is how I search arrays in a Mirth js transformer:
var Yak = [];
Yak.push('test');
if(Yak.indexOf('test') != -1)
{
// do something
}
Does this give you error?
Mirth uses the Rhino engine for Javascript, and on some earlier versions of the JVM, indexOf appeared to not be supported on arrays. Since upgrading our JVM to 1.6.23 (or higher), indexOf has started working. However, we still have legacy code that, when searching arrays of strings, I just use a loop each time:
var compareString = "blah";
var index = -1;
for (var i = 0; i < myArray.length; ++i)
{
if (myArray[i] == compareString)
{
index = i;
break;
}
}
If you need to do this frequently, you should be able to use a code template to manually add the indexOf function to Array.
Set the code template to global access, and try out something like this (untested code):
Array.prototype.indexOf = function(var compareObject)
{
for (var i = 0; i < myArray.length; ++i)
{
// I don't think this is actually the right way to compare
if (myArray[i] == compareObject)
{
return i;
}
}
return -1;
}
var arr = ['john',1,'Peter'];
if(arr.indexOf('john') > -1)
{
//match. what to do?
console.log("found");
}
else
{
console.log("not found");//not found .. do something
}
var i = ['a', 'b', 'c']
if(i.indexOf('a') > -1)
{
///do this, if it finds something in the array that matches what inside the indexOf()
}
else
{
//do something else if it theres no match in array
}