Creating procedure or function in Ada task - concurrency

I am creating the following task in Ada and I want it to contain a procedure that tells me the count of my buffer. How can I do that?
package body Buffer is
task body Buffer is
size: constant := 10000; -- buffer capacity
buf: array(1.. size) of Types.Item;
count: integer range 0..size := 0;
in_index,out_index:integer range 1..size := 1;
begin
procedure getCount(currentCount: out Integer) is
begin
currentCount := count;
end getCount;
loop
select
when count<size =>
accept put(item: in Types.Item) do
buf(in_index) := item;
end put;
in_index := in_index mod size+1;
count := count + 1;
or
when count>0 =>
accept get(item:out Types.Item) do
item := buf(out_index);
end get;
out_index := out_index mod size+1;
count := count - 1;
or
terminate;
end select;
end loop;
end Buffer;
end Buffer;
When I compile this code I get an error that
declarations must come before "begin"
referring to the definition of the getCount procedure.

A declaration must come before "begin", and your declaration of "getCount" is following the "begin". Relocate it:
procedure getCount(currentCount: out Integer) is
begin
currentCount := count;
end getCount;
begin
But really, pay attention to trashgod's advice.

The immediate problem is that you have specified a subprogram body without having first specified a corresponding subprogram declaration in the handled sequence of statements part of your task body. It should go in the declarative part, as shown here.
The larger problem appears to be creating a bounded buffer, for which a protected type seems more suitable. Examples may be found in §II.9 Protected Types and §9.1 Protected Types. In protected type Bounded_Buffer, you could add a
function Get_Count return Integer;
having a body like this:
function Get_Count return Integer is
begin
return Count;
end Get_Count;

Related

Problem: String writes over another string

I'm trying to process two strings using the following code. The result works just fine but whenever I try to do the same operation for the second string, the first string gets written over by the second's value. for an example if the first string = "fuhg" and second string equals ="abc" first string becomes: "abcg".
It probably has to do with memory allocation or something alike but I can't figure it out as I'm not very good in that area.
string newPassChar;
string newBloom=bloomFilter(newPass);
int index=0;
for ( int k =0 ; k < alpha.length() ; k++ )
{
if (newBloom[k]=='1')
{
newPassChar[index]=alpha[k];
index++;
}
}
From cppreference std::basic_string::operator[]:
No bounds checking is performed. If pos > size(), the behavior is undefined.
From cppreference std::basic_string construcor:
1) Default constructor. Constructs empty string (zero size and unspecified capacity).
So:
string newPassChar;
creates new string with size() == 0.
Then:
newPassChar[0] = ...
will overwrite the null character in the string. But on the next iteration, when index = 1, then:
newPassChar[1] = ....
it is undefined behavior. and spawns demons.
I think you want to "push_back" the characters as you read them:
newPassChar.push_back(alpha[k]);
There no need to store another "index" variable used for indexing the string, the string object itself it knows it's size, it's available in size() method.

Access a nested ROS-Message

I would like to access the second element of ROS-Message message_a.
# ROS-Message message_a
Header header
message_b[] test
ROS-Message 1 contains ROS-Message 2!
# ROS-Message message_b
Header header
uint32[] result
In my main code I loop with a for-each loop through the message test with the datatyp message_a.
for ( message_a::Test1 test : message_a.message_b ) {
uint32_t c = test.result;
}
How can I access for example the second element of message_b? I need that because I want to get the result of the second test.
With the for-each loop that you see above, it will loop through all elements of message_b. How can I change this for-each loop to a general for-loop? Then I could just loop from 2 to 3...
You can change the range-based (aka for-each) loop to an index based for loop like this which iterates over the second, third, ..., and final result of test 42:
std::size_t test_idx = 42; // Second element of results
std::size_t result_start = 1; // start from the second result
std::size_t result_end = your_msg_obj.test.at(test_idx).size(); // run until end of all in the given test
// For loop that iterates over all results in a given test
for ( std::size_t result_idx = result_start; idx < result_end; ++idx ) {
uint32_t c = your_msg_obj.test.at(test_idx).result.at(result_idx);
// ... fancy stuff
}
The ROS documentatation of messages explains that array message fields are generated as std::vector in C++. In your case the field test is of type std::vector<message_b>, result of type std::vector<uint32_t>.
C++ vectors can be accessed in serval ways, you can find them in in this answer. In your case simply accessing the items by index should be possible like:
for(size_t i = 0; i != your_message_a.test.size(); i++)
{
//Access the second result item of each test item
uint32_t c = your_message_a.test[i].result[1];
}

How can I return an array/record set of my own structure form Oracle’s procedure

I am new in Oracle and have a problem. We like to write a procedure which will read data from a table and do some processing on each row and then return the resultant data. Its means the resultant data will have same number of rows but each column type can’t be same. Here this procedure I want to use like a C++ function which return a vector of structure.
TABLE structure is as follows
FIRST int
Second VARCHAR2(20)
Third int
Then the return structure would be
FIRST int
Second int
Third int;
Fourth int;
In short how can I return an array/record set of my own data structure form Oracle’s procedure.
There are at least two ways to do it:
Table function:
CREATE FUNCTION <YOUR_NAME_OF_FUNCTION> (...)
RETURN <TABLE_TYPE> AS
l_table := ();
BEGIN
FOR i IN 1 .. N
LOOP
l_table.extend;
l_table(l_table.last) := (some, data, for, table, type);
END LOOP;
RETURN l_tab;
END;
Pipelined table function
CREATE FUNCTION <YOUR_NAME_OF_FUNCTION> (...)
RETURN <TABLE_TYPE> PIPELINED AS
BEGIN
FOR i IN 1 .. N
LOOP
PIPE ROW((some, data, for, table, type));
END LOOP;
RETURN;
END;
to select from this functions:
SELECT *
FROM TABLE(<YOUR_NAME_OF_FUNCTION>(...))
<TABLE_TYPE> is something like:
CREATE tab_type is table of NUMBER(10)
Pipelined functions have to work faster than table function, because they return every row as the row is prepared, table function prepare all rows and then return them at once.
To read more check this article

Debug Assertion Failed! String manipulation using pointer arithmetic

EDIT: Pastebin links to the entirety of the code at the bottom
for my CS215 course, I was given a class called String215 which is a basic string class to help in the understanding of dynamic memory allocation and pointer arithmetic with char arrays.
The class was given to me in a very basic skeleton form with prototypes but no implementations, along with a test function to test my implementations. I CAN NOT use any C String functions in this assignment.
The part of the program which is troubling is the append function, which just appends a parameter string215 object to the end of the current string215 object.
// Add a suffix to the end of this string. Allocates and frees memory.
void string215::append(const string215 &suffix)
{
char *output = new char[str_len(data)+suffix.length()+1];
for(int x = 0; x < str_len(data); x++) {
*output = *data;
output++;
data++;
}
for(int x = 0; x < suffix.length(); x++) {
*output = suffix.getchar(x);
output++;
}
*output = '\0';
output -= (str_len(data)+suffix.length()+1);
delete[] data;
data = output;
}
This portion of the code is tested in the 13th test of the test function as shown here:
string215 str("testing");
...
// Test 13: test that append works in a simple case.
curr_test++;
string215 suffix("123");
str.append(suffix);
if (strcmp(str.c_str(), "testing123") != 0) {
cerr << "Test " << curr_test << " failed." << endl;
failed++;
}
Here is the description of the append class:
Add the suffix to the end of this string. Allocates a new, larger, array; copies the old contents, followed by the suffix, to the new array; then frees the old array and updates the pointer to the new one.
My program aborts at the very end of the append function execution with the error message:
Debug Assertion Failed!
Program: [Source path]\dbgdel.cpp
Line: 52
Expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)
...
Abort || Retry || Ignore
I'm fairly certain it has something to do with my very poor memory management. I know it's not a lot to go on, but I've been struggling with this for hours on end and can't seem to figure it out.
Here's a pastebin of the .cpp and .h file for this program
string215.cpp: http://pastebin.com/Xh2SvDKJ
string215.h: http://pastebin.com/JfAJDEVN
Any help at all is greatly appreciated!
Thanks,
RAW-BERRY
You are changing data pointer before delete[]. You need to delete[] exactly the same value you got from new[].
Also, you are incrementing output pointer str_len(data)+suffix.length() times, and you take it back by str_len(data) + suffix.length() + 1.
I would use separate variables for iteration to solve these problems.
You increment output exactly str_len(data) + suffix.length() times. Note that you don't increment output after *output = '\0';.
So to go back to the start, you should use:
output -= (str_len(data) + suffix.length());
By the way, some of the code is not very efficient. For example, getchar uses a loop instead of simply returning data[index]. You use getchar in append, which means that the performance isn't great.
EDIT: As zch says, you use delete[] data after modifying data, but note that even before that you use str_len(data) after modifying data (when deciding how many bytes to go skip back), so the calculation is wrong (and my suggestion above is also wrong, because str_len(data) is now zero).
So I think your problem is with the line
for(int x = 0; x < str_len(data); x++) {
Notice that the size of 'data' is changing at each iteration of the loop. As you increment 'x', you are decreasing the length of 'data'. Suppose 'data' is a string holding "hello": in the first iteration of the loop x=0 and str_len(data)=5; in the second iteration x=1 and str_len(data)=4. Thus the for loop executes half as many times as you need it to and 'data' does not end up pointing to the end of the data string

Passing an array to a function, but if it doesn't return true I want to pass an extra digit?

So for my code I want to pass an argument to a function and if it doesn't return true, I want it to pass the next index digit in the int array.
So if areaIntA[0] = 0; doesn't return true, I want it to pass areaIntA[0][1] = 01; and if that doesn't return true, areaIntA[0][1][2] = 012; etc...
My updated code:
areaInt = areaIntA[0];
do {
areaCheck = isRegistered(file, areaInt);
if (areaCheck != 1)
{
areaInt = areaIntA[i] * 10 + areaIntA[i+1];
i++;
}
} while (areaCheck != 1);
cout << areaCheck << endl;
This compiles but it shows a segmentation error, anyone know why?
Have the function take in a list (vector). for every call add a new element to the end.
eg.
List< int?> areaIntList;
do {
areaIntList.Add(areaInt[i]);
areaCheck = isRegistered(file, areaInt[i]);
if (areaCheck != 1)
{
i++;
}
} while (areaCheck != 1);
isRegistered takes in a List of your used type.
You're weirdly equating array integer values in a sort of string context. That usually means base-10 math.
Try:
int val = 0;
do {
val = 10 * val + areaInt[i];
areaCheck = isRegistered(file, val);
if (areaCheck != 1)
i++;
} while (areaCheck != 1);
On the first pass, val will be the value of areaInt[0]; On the second pass, it will be areaInt[0] followed by areaInt[1] (e.g. 0 and 1 become 1, 1 and 2 become 12). And so on.
My understanding of your question is this:
isRegistered is a function that takes a file and a variable-length string of digits, returning 1 if the string is registered and 0 otherwise.
areaInt is a C-style string like "31526".
What you want is to see if "3" is registered; if not, see if "31" is registered; if not, try "315", etc until all the digits of areaInt are exhausted.
The end result should be a substring of areaInt which is the shortest registered string, or an error if no registered string was found.
This is how I'd do it.
If the input string areaInt is empty, return an error.
Loop a counter i from 1 to the length of the string:
Construct a test string s from the first i characters in areaInt.
Test if s is registered. If it is, break out of the loop and return s. If not, continue the loop.
If the loop completes at the end of areaInt and no registered string has been found, return an error.
Note. Make sure you stop at the end of areaInt. Otherwise if you get to the end of areaInt and still haven't found a string that is registered, then you will overrun the buffer and try to read an element not in the string.