pass by value not supported XDP - c

I am creating a function to loop through some loops and try to match a set. It is supposed to work fine, but unfortunately, it is not. I get a "pass by value not supported" error. How can I fix this?
int matchSet(Program p, int match[], int action)
{
int matchState = 0;
int match[4] = {3,4,5,6}; //set as example
int p.set[10] = {2,1,3,4,5,6,9,10,11,12}; //set as example (normal p.set)
for (int i = 0; i < 10; i++)
{
if (matchState != 2)
{
if (p.set[i] == match[0] && p.set[i + 1] == match[1])
{
matchState = 0;
for (int j = 0; j <= 4; j++)
{
bpf_printk("test");
if (matchState == 0)
{
bpf_printk("test3");
if (p.set[i] != match[j])
{
bpf_printk("test4");
matchState = 1;
break;
}
}
}
if (matchState == 0)
{
bpf_printk("test6");
matchState = 2;
}
}
}
}
if(matchState == 2) {
return action;
}
}
I call the function by:
Program p;
.....
int set[10] = {2,1,3,4,5,6,9,10,11,12};
p.set = set;
int match[4] = {3,4,5,6};
matchSet(p, match, 1);
Error:
error: pass by value not supported 0x1aca7c8: i64 = GlobalAddress<i32 (%struct.Program*, i8*, i32)* #matchSet> 0

You need to change your function to take a pointer to a Program like so:
int matchSet(Program *p, int match[], int action){
...
And then also change your callsite:
Program p;
matchSet(&p, match, 1);

Related

Anyone know why this code gives wrong output in leet code and works fine in vs code

so basically i am trying to solve a leet code problem called [two sum II] using hashing
but i am getting error in this test case 1,2,3,4,4,9,56,90 where i have to find two index those elements sum is equal to target 8
well the answer of this test case is 4,5 because the sum of index4 and index5 in array[1-8] is 8
Here the problem is when i compiled this below code in vs code it works perfectly fine and gives correct output 4,5
but during leet code submission it throws wrong answer and showing output 1,3 instead of 4,5
// here is my hash implemention code
#include <stdio.h>
#include <stdlib.h>
typedef struct Hash {
int value;
int index;
struct Hash *next;
} hash;
hash *Hashes[10];
int hashify(int value) { return abs(value) % 10; }
void insert(int value, int index) {
int key = hashify(value);
if (Hashes[key] == NULL) {
Hashes[key] = malloc(sizeof(hash));
Hashes[key]->value = value;
Hashes[key]->index = index;
Hashes[key]->next = NULL;
return;
}
hash *ptr = Hashes[key];
while (ptr->next != NULL) ptr = ptr->next;
ptr->next = malloc(sizeof(hash));
ptr->next->value = value;
ptr->next->index = index;
ptr->next->next = NULL;
return;
}
int search(int value) {
int key = hashify(value);
if (Hashes[key] == NULL) return -1;
if (Hashes[key]->value == value)
return Hashes[key]->index;
else {
hash *ptr = Hashes[key]->next;
while (ptr != NULL) {
if (ptr->value == value) return ptr->index;
ptr = ptr->next;
}
return -1;
}
}
// here is hash_free function
void Hash_free() {
for (int i = 0; i < 10; i++) {
if (Hashes[i] == NULL)
continue;
else {
if (Hashes[i]->next == NULL) {
free(Hashes[i]);
Hashes[i] = NULL;
} else {
hash *ptr;
while (ptr != NULL) {
ptr = Hashes[i]->next;
free(Hashes[i]);
Hashes[i] = ptr;
}
}
}
}
}
// here is two sum function code
int *twoSum(int *numbers, int numbersSize, int target, int *returnSize) {
int *result;
if (numbersSize == 2) {
result = malloc(2 * sizeof(int));
result[0] = 1;
result[1] = 2;
*returnSize = 2;
return result;
} else {
int val, element;
for (int i = 0; i < numbersSize; i++) {
val = target - numbers[i];
element = search(val);
if (element != -1) {
result = malloc(2 * sizeof(int));
if (element < i) {
result[0] = element + 1;
result[1] = i + 1;
} else {
result[0] = i + 1;
result[1] = element + 1;
}
*returnSize = 2;
Hash_free();
return result;
}
insert(numbers[i], i);
}
}
return NULL;
}
// here is main code
int main() {
int numbers[] = {1, 2, 3, 4, 4, 9, 56, 90};
int target = 8;
int numberSize = sizeof(numbers) / sizeof(int);
int returnSize;
int *res = twoSum(numbers, numberSize, target, &returnSize);
for (int i = 0; i < returnSize; i++) {
printf("%d ", res[i]);
}
free(res);
return 0;
}
Your "hash" variable is global, so it keeps preserving data of previous testcase executed. I have faced the same when using global variable.
Solution:
Just clear your hash or initialize it, in your main function( or the entry point function), so that it will ensure a fresh start for each of the test cases those are executed.

Segfault in Merge - Sort in C

I am trying to sort an array of structures of size 5500 using merge sort.
However, I am getting a segmentation fault pretty quickly because I am not allowed to use VLA. so I have to create 2 extra arrays of size 5500 each time I call merge-sort recursively.
I would appreciate a fix for my problem. I will provide my code here:
void merge(Student rightArr[], Student leftArr[], Student mergedArr[], int sizeOfRight, int sizeOfLeft) {
int rightArrIndex = 0;
int leftArrIndex = 0;
int mergedArrIndex = 0;
while (leftArrIndex < sizeOfLeft && rightArrIndex < sizeOfRight) {
char *ptrLeft, *ptrRight;
long gradeLeft = strtol(leftArr[leftArrIndex].grade, &ptrLeft, BASE_COUNT);
long gradeRight = strtol(rightArr[rightArrIndex].grade, &ptrRight, BASE_COUNT);
if (gradeLeft > gradeRight) {
mergedArr[mergedArrIndex] = rightArr[rightArrIndex];
rightArrIndex++;
} else {
mergedArr[mergedArrIndex] = leftArr[leftArrIndex];
leftArrIndex++;
}
mergedArrIndex++;
}
if (leftArrIndex == sizeOfLeft) {
for (int i = mergedArrIndex; i < (sizeOfLeft + sizeOfRight); i++) {
mergedArr[i] = rightArr[rightArrIndex];
rightArr++;
}
} else {
for (int i = mergedArrIndex; i < (sizeOfLeft + sizeOfRight); i++) {
mergedArr[i] = leftArr[leftArrIndex];
leftArr++;
}
}
}
void mergeSort(Student studentsArray[], int amountOfStudents) {
if (amountOfStudents <= 1) {
return;
}
int leftSize = (amountOfStudents / 2);
int rightSize = (amountOfStudents - leftSize);
Student leftArr[5500], rightArr[5500];
for (int i = 0; i < leftSize; i++) {
leftArr[i] = studentsArray[i];
}
for (int i = 0; i < rightSize; i++) {
rightArr[i] = studentsArray[i + leftSize];
}
mergeSort(leftArr, leftSize);
mergeSort(rightArr, rightSize);
merge(rightArr, leftArr, studentsArray, rightSize, leftSize);
}
Ok, I think this should do what you want. It assumes that Student and BASE_COUNT have been defined:
#include <stdlib.h>
#include <stdio.h>
void merge(Student studentsArr[],
int leftSize, int rightSize,
Student scratchArr[])
{
Student *leftArr = studentsArr;
Student *rightArr = studentsArr + leftSize;
int leftIx = 0, rightIx = 0, mergeIx = 0, ix;
while (leftIx < leftSize && rightIx < rightSize) {
long gradeLeft = strtol(leftArr[leftIx].grade, NULL, BASE_COUNT);
long gradeRight = strtol(rightArr[rightIx].grade, NULL, BASE_COUNT);
if (gradeLeft <= gradeRight) {
scratchArr[mergeIx++] = leftArr[leftIx++];
}
else {
scratchArr[mergeIx++] = rightArr[rightIx++];
}
}
while (leftIx < leftSize) {
scratchArr[mergeIx++] = leftArr[leftIx++];
}
// Copy the merged values from scratchArr back to studentsArr.
// The remaining values from rightArr (if any) are already in
// their proper place at the end of studentsArr, so we stop
// copying when we reach that point.
for (ix = 0; ix < mergeIx; ix++) {
studentsArr[ix] = scratchArr[ix];
}
}
void mergeSortInternal(Student studentsArray[],
int amountOfStudents,
Student scratchArr[])
{
if (amountOfStudents <= 1) {
return;
}
int leftSize = amountOfStudents / 2;
int rightSize = amountOfStudents - leftSize;
mergeSortInternal(studentsArray, leftSize, scratchArr);
mergeSortInternal(studentsArray + leftSize, rightSize, scratchArr);
merge(studentsArray, leftSize, rightSize, scratchArr);
}
#define MAX_ARR_SIZE 5500
void mergeSort(Student studentsArray[], int amountOfStudents)
{
if (amountOfStudents <= 1) {
return;
}
if (amountOfStudents > MAX_ARR_SIZE) {
fprintf(stderr, "Array too large to sort.\n");
return;
}
Student scratchArr[MAX_ARR_SIZE];
mergeSortInternal(studentsArray, amountOfStudents, scratchArr);
}
The top-level sort function is mergeSort, defined as in the original post. It declares a single scratch array of size MAX_ARR_SIZE, defined as 5500. The top-level function is not itself recursive, so this scratch array is only allocated once.

My BFS code is only showing the direct paths from source to destination, but not all possible paths

I want to print all possible paths from a given source and destination. But in my BFS code, it only shows the two paths, not the multiple path. For a directed graph where n = 4, edge = 6, given,
1-2
1-3
1-5
5-3
5-4
3-4
3-2
It should've printed 3 paths:
1-5-4
1-3-4
1-5-3-4
But it only shows this two paths
1-3-4
1-5-4
This is my sample code for finding the src to destination path
#include <stdio.h>
int queue1[100], state[100], parent[100];
int front = 0, rear = -1, maxSize = 100;
int count = 0;
int initial = 1, waiting = 2, visited = 3;
int n, e;
int adj[100][100];
bool isEmpty()
{
return count == 0;
}
bool isFull()
{
return count == maxSize;
}
void enqueue(int val)
{
if (!isFull())
{
if (rear == maxSize - 1)
{
rear = -1;
}
rear++;
queue1[rear] = val;
count++;
}
}
int dequeue()
{
int val = queue1[front];
front++;
if (front == maxSize)
{
front = 0;
}
count--;
return val;
}
void BFS_Traversal(int src, int des)
{
int done = 0;
enqueue(src);
state[src] = waiting;
parent[src] = -1;
printf("path ");
while (!isEmpty() && done == 0)
{
src = dequeue();
// printf("%d ",src);
state[src] = visited;
for (int i = 1; i <= n; i++)
{
if (adj[src][i] == 1 && state[i] == initial)
{
enqueue(i);
state[i] = waiting;
parent[i] = src;
if (i == des)
{
state[i] = initial;
int k = des;
do
{
printf("%d ", k);
k = parent[k];
} while (k != -1);
printf("\n");
}
}
}
}
}
int main()
{
int src, start, end, des;
scanf("%d%d", &n, &e);
for (int i = 1; i <= e; i++)
{
scanf("%d%d", &start, &end);
adj[start][end] = 1;
}
for (int i = 1; i <= n; i++)
{
state[i] = initial;
}
for (int k = 1; k <= n; k++)
{
parent[k] = -1;
}
scanf("%d%d", &src, &des);
BFS_Traversal(src, des);
}
As, you can see 1-5-3-4 path is not showing because they are already visited. How should I modify this code to print all possible paths?

gSOAP: How to compare two value-structs (with JSON-content) in C?

I´m using gSOAP (in C) for a client application, which is calling a Java-webservice. I´m using the function json_call().
I have a request-struct filled with the JSON-input-data and I get a response-struct filled with the JSON-output-data from the Java-service. Both JSONs have the same structure in general, but can have more, less or changed elements.
My task now is to find out, in which elements the response is different from the request. The main-element is a large array with a lot of members, like:
{
"objects": [
{
"#id": "OBJ00001",
"name": "value",
...
},
{
"#id": "OBJ00002",
"number": 123,
...
},
...
]
}
I can identify any object of the same kind with the #id field.
It´s simple to iterate the objects array with something like:
for(i = 0; i < has_size(value_at(response, "objects")); i++)
But then I´missing a function, which can compare members ("objects") with the same #id in request and response. Something like "findMemberWithSameField" and then "equal" (which both does not exist!):
struct member *currentMemberInResponse = NULL;
struct member *memberWithSameField = NULL;
for(i = 0; i < has_size(value_at(response, "objects")); i++)
{
/* get the current member out of the response array */
currentMemberInResponse = nth_value(value_at(response, "objects"), i);
/* Find member/object with same #id in request */
memberWithSameField = findMemberWithSameField(value_at(request, "objects"), currentMemberInResponse , "#id"));
/* equal is true if all fields are the same */
if(equal(currentMemberInResponse, memberWithSameField))
{
/* Do nothing, because nothing changed */
}
else
{
/* Do something */
}
}
Any idea on that task? Otherwise I have to do write my own "findMemberWithSameField" and "euqal".
Kind regards Daniel
The JSON C++ API defines operator== to compare two objects recursively. The latest version 2.8.55 works (I've tested) to compare two JSON objects, where operator== calls the following function:
bool json_eqv(const value& x, const value& y)
{
...
switch (x.__type)
{
...
case SOAP_TYPE__struct:
if (x.size() != y.size())
return false;
else
{
const _struct& s = x;
const _struct& t = y;
for (_struct::iterator i = s.begin(); i != s.end(); ++i)
{
_struct::iterator j;
for (j = t.begin(); j != t.end(); ++j)
if (!strcmp(i.name(), j.name()))
break;
if (j == t.end() || *i != *j)
return false;
}
return true;
}
This can be rewritten to C with something like:
int json_eqv(const value *x, const value *y)
{
if (x->__type != y->__type &&
(x->__type != SOAP_TYPE__i4 || y->__type != SOAP_TYPE__int) &&
(x->__type != SOAP_TYPE__int || y->__type != SOAP_TYPE__i4))
return false;
switch (x->__type)
{
case SOAP_TYPE__boolean:
case SOAP_TYPE__i4:
case SOAP_TYPE__int:
return int_of(x) == int_of(y);
case SOAP_TYPE__double:
return double_of(x) == double_of(y);
case SOAP_TYPE__string:
case SOAP_TYPE__dateTime_DOTiso8601:
return !strcmp(string_of(x), string_of(y));
case SOAP_TYPE__struct:
if (has_size(x) != has_size(y))
return 0;
else
{
size_t i, j;
for (i = 0; i < has_size(x); ++i)
{
for (j = 0; j < has_size(y); ++j)
if (!strcmp(nth_member(x, i), nth_member(y, j))
break;
if (j == has_size(y) || !json_eqv(nth_value(x, i), nth_value(y, j))
return 0;
}
return 1;
}
case SOAP_TYPE__array:
if (has_size(x) != has_size(y))
return 0;
else
{
int i;
for (i = 0 ; i < has_size(x); ++i)
if (!json_eqv(nth_nth(x, i), nth_nth(y, i))
return 0;
return 1;
}
default:
return 0;
}
}

Having issues with pointers

I'm fairly new to programming and i'm having problem with pointers. My code below works with the exception for that my counts doesn't follow with my article number when i sort it. I probably need pointers to get this working but I don't know how.
Can anyone help me?
void printMenu(void)
{
printf("\nMENU:\n");
printf("(D)isplay the menu\n");
printf("(G)enerate inventory\n");
printf("(P)rint inventory\n");
printf("(L)inear search article\n");
printf("(B)inary search article\n");
printf("(I)nsertion sort inventory\n");
printf("B(u)bble sort inventory\n");
printf("(M)erge sort inventory\n");
printf("(Q)uit program\n");
}
void generateInventory(article inventory[], int noOfArticles,
int minArticleNumber, int maxArticleNumber, int maxNoOfArticles)
{
int i, j;
int idCount[] =
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };
for (i = 0; i < noOfArticles; i++)
{
inventory[i].id = rand() % (maxArticleNumber - minArticleNumber + 1) +
minArticleNumber;
idCount[inventory[i].id - 1] = idCount[inventory[i].id - 1] + 1;
for (j = 0; j <= i; ++j)
{
if (idCount[inventory[i].id - 1] > 1)
{
inventory[i].id = rand() % (maxArticleNumber + minArticleNumber);
}
}
inventory[i].counts = rand() % maxNoOfArticles;
}
}
void printInventory(const article inventory[], int noOfArticles)
{
int i;
printf("\nINVENTORY\n");
printf("%7s %8s\n", "Article", "Count");
for (i = 0; i < noOfArticles; i++)
{
printf("%7d %8d\n", inventory[i].id, inventory[i].counts);
}
}
int getArticleId()
{
int id;
printf("\nGive article id: ");
scanf("%d", &id);
return id;
}
void printSearchResult(const article inventory[], int index)
{
if (index == -1)
{
printf("\nArticle not found\n");
}
else
{
printf("\nArticle id: %d\n", inventory[index].id);
printf("Article counts: %d\n", inventory[index].counts);
}
}
int linearSearchInventory(const article inventory[], int noOfArticles, int id)
{
int i = 0;
int index = -1;
while (index == -1 && i < noOfArticles)
{
if (id == inventory[i].id)
{
index = i;
}
i++;
}
}
int binarySearchInventory(const article inventory[], int noOfArticles, int id)
{
int index = -1;
int left = 0;
int right = noOfArticles - 1;
int middle;
while (index == -1 && left <= right)
{
middle = (left + right) / 2;
if (id == inventory[middle].id)
{
index = middle;
}
else if (id < inventory[middle].id)
{
right = middle - 1;
}
else
{
left = middle + 1;
}
}
return index;
}
void insertionSortInventory(article inventory[], int noOfArticles)
{
int i, j;
int next;
for (i = 1; i < noOfArticles; i++)
{
next = inventory[i].id;
j = i - 1;
while (j >= 0 && next < inventory[j].id)
{
inventory[j + 1].id = inventory[j].id;
j = j - 1;
}
inventory[j + 1].id = next;
}
}
void bubbleSortInventory(article inventory[], int noOfArticles)
{
int c, d, t;
for (c = 0; c < (noOfArticles - 1); c++)
{
for (d = 0; d < noOfArticles - c - 1; d++)
{
if (inventory[d].id > inventory[d + 1].id)
{
t = inventory[d].id;
inventory[d].id = inventory[d + 1].id;
inventory[d + 1].id = t;
}
}
}
}
void mergeSortInventory(article inventory[], int noOfArticles)
{
int temp[noOfArticles / 2];
int nLeft, nRight;
int i, iLeft, iRight;
if (noOfArticles > 1)
{
nLeft = noOfArticles / 2;
nRight = (int) ceil((double) noOfArticles / 2);
mergeSortInventory(inventory, nLeft);
mergeSortInventory(&inventory[noOfArticles / 2], nRight);
for (i = 0; i < nLeft; i++)
{
temp[i] = inventory[i].id;
}
i = 0;
iLeft = 0;
iRight = 0;
while (iLeft < nLeft && iRight < nRight)
{
if (temp[iLeft] < inventory[noOfArticles / 2 + iRight].id)
{
inventory[i].id = temp[iLeft];
iLeft = iLeft + 1;
}
else
{
inventory[i].id = inventory[noOfArticles / 2 + iRight].id;
iRight = iRight + 1;
}
i = i + 1;
}
while (iLeft < nLeft)
{
inventory[i].id = temp[iLeft];
i = i + 1;
iLeft = iLeft + 1;
}
}
}
If I'm correct in what you're asking, you want to keep the idCount array relational to the inventory array. I assume, since you're using article as a type that you've either typedef'd a variable to be an article, which would be pointless, or more likely you've built a struct of type article, then made an array of those structs, and called the array inventory.
If this is the case, then the most likely method of keeping them relational is to just include the count in the article struct.
There are methods of making the arrays relational without doing that, but they're pointless, because a simple four-line struct would do the trick, even if that struct was a wrapper around a different struct, or a header for another struct.
When sorting your records, you only assign the id member of your struct:
inventory[foo].id = inventory[bar].id;
You should assign the complete struct:
inventory[foo] = inventory[bar];
Just remember that temporaries must be of type article an not int so they allso can be assigne a complete struct and not only an id value

Resources