I have a vector<vector <string>> a; How could I pass it to the enclave? How I declare edl function.
A sample function declaration for the app, edl and enclave is much appreciated.
I am aware of this: C++ Arguments to SGX Enclave Edge Functions.
A sample to pass even a vector<string> is ok for me.
update1:
I came up with this:
App.cpp
const char *convert(const std::string & s)
{
return s.c_str();
}
vector<string> members_data;
member_data.push_back("apple");
member_data.push_back("orange"); //just for sample
std::vector<const char*> vc;
std::transform(members_data.begin(), members_data.end(), std::back_inserter(vc), convert);
edl:
trusted {
public void ecall_receive_vector([in, size=len] const char **arr, size_t len);
};
enclave
void ecall_receive_vector(const char *arr[], size_t len)
{
vector<string> v(arr, arr+len);
printf("%s\n", v[2].c_str());
}
But enclave does not receive any data, the program compiles perfectly with no error. Could anyone help? The printf is the sample ocall.
In the EDL use count instead of size.
trusted {
public void ecall_receive_vector([in, count=len] const char **arr, size_t len);
};
You are passing a double pointer, it is, a pointer to pointer to char (char **).
While marshaling/unmarshaling pointers, the EDL Processor processes (copies and validates input and output) only the first level of indirection, it's up to the developer to handle the additional levels of indirection. Hence, for an array of pointers it will only copy the first array of pointers, not the pointed values, copying them is the developer's responsibility.
If not specified count and size default to 1 and sizeof(<pointed-type>) respectively. In your case size = sizeof(<pointer>) which in most platforms is 4.
In your case, you provided only size. As you don't provide the caller code I assume you're passing the length of the string, and as count was not specified it defaults to 1. Then the total number of bytes, based on Total number of bytes = count * size will be 1 * len which is wrong.
Using only count will let size default to sizeof(<pointed-type>), then Total number of bytes = count * size will be count * sizeof(<pointed-type>), which is right because you're passing an array of pointers.
To close, once inside the Enclave you need to copy the pointers' data because those pointers reside out of the enclave, that may be done automatically by assigning them to a std::string.
From Intel SGX SDK Documentation:
Pointer Handling (the last paragraph)
You may use the direction attribute to trade protection for performance. Otherwise, you must use the user_check attribute described below and validate the data obtained from untrusted memory via pointers before using it, since the memory a pointer points to could change unexpectedly because it is stored in untrusted memory. However, the direction attribute does not help with structures that contain pointers. In this scenario, developers have to validate and copy the buffer contents, recursively if needed, themselves.
And,
Buffer Size Calculation
The generalized formula for calculating the buffer size using these attributes:
Total number of bytes = count * size
The above formula holds when both count and size/sizefunc are specified.
size can be specified by either size or sizefunc attribute.
If count is not specified for the pointer parameter, then it is assumed to be equal to 1, i.e., count=1. Then total number of bytes equals to size/sizefunc.
If size is not specified, then the buffer size is calculated using the above formula where size is sizeof (element pointed by the pointer).
Related
When I call gethostname using a char my length 25 but when I use a string my length is 64. Not really sure why. Both of them I am declaring the same size on HOST_NAME_MAX.
char hostname[HOST_NAME_MAX];
BOOL host = gethostname(hostname, sizeof hostname);
expectedComputerName = hostname;
int size2 = expectedComputerName.length();
std::string test(HOST_NAME_MAX, 0);
host = gethostname(&test[0], test.length());
int testSize = test.length();
An std::string object can contain NULs (i.e. '\0' characters). You are storing the name in the first bytes of a string object that was created with a size of HOST_NAME_MAX length.
Storing something in the beginning of the string data won't change the length of the string that remains therefore HOST_NAME_MAX.
When creating a string from a char pointer instead the std::string object created will contain up to, but excluding, the first NUL character (0x00). The reason is that a C string cannot contain NULs because the first NUL is used to mark the end of the string.
Consider what you're doing in each case. In the former code snippet, you're declaring a character array capable of holding HOST_NAME_MAX-1 characters (1 for the null terminator). You then load some string data into that buffer via the call to gethostname and then print out the length of buffer by assigning it to a std::string object using std::string::operator= that takes a const char *. One of the effects of this is that it will change an internal size variable of std::string to be strlen of the buffer, which is not necessarily the same as HOST_NAME_MAX. A call to std::string::length simply returns that variable.
In the latter case, you're using the std::string constructor that takes a size and initial character to construct test. This constructor sets the internal size variable to whatever size you passed in, which is HOST_NAME_MAX. The fact that you then copy in some data to std::strings internal buffer has no bearing on its size variable. As with the other case, a call to the length() member function simply returns the size - which is HOST_NAME_MAX - regardless of whether or not the actual length of the underlying buffer is smaller than HOST_NAME_MAX.
As #MattMcNabb mentioned in the comments, you could fix this by:
test.resize( strlen(test.c_str()) );
Why might you want to do this? Consistency with the char buffer approach might be a reason, but another reason may be performance oriented. In the latter case you're not only outright setting the length of the string to HOST_NAME_MAX, but also its capacity (omitting the SSO for brevity), which you can find starting on line 242 of libstdc++'s std::string implementation. What this means in terms of performance is that even though only, say, 25 characters are actually in your test string, the next time you append to that string (via +=,std::string::append,etc), it's more than likely to have to reallocate and grow the string, as shown here, because the internal size and internal capacity are equal. Following #MattMcNabb's suggestion, however, the string's internal size is reduced down to the length of the actual payload, while keeping the capacity the same as before, and you avoid the almost immediate re-growth and re-copy of the string, as shown here.
string str; str="hello"; str.length(); sizeof(str);
I see that str.length returns the length in bytes why sizeof(str) doesn't return the same?
Is there alternative in c++ to a c command which is strlen(str)? What is the alternative of this coomand in c++?
When I use winsock in the send function I return the length in bytes. What should I use?
str.length? Or sizeof(str)? Pr something else? Because I see they produce different results.
sizeof returns the size of the data structure, not the size of the data in contains.
length() returns the length of the string that str contains, and is the function you want
It might seem confusing because sizeof(char[30]) is 30, but that is because the size of the data structure is 30, and will remain 30 no matter what you put in it
The string is actually an extremely complicated structure, but suppose it was a simple class with a pointer and a length
class string
{
char *data;
int length;
};
then sizeof(string) would return:
The size of a char * pointer, possibly but not necessarily 4
plus the size of an int, possibly but not necessarily 4
So you might get a value of 8. What the value of data or length is has no effect on the size of the structure.
sizeof() is not really meant to be used on a string class. The string class doesn't store ONLY the string data; there would be no difference between its data and a C-style string; it has other stuff in it as well, which throws off sizeof(). To get the actual length of the characters in the string, use str.length().
Don't use the C strlen() on a C++ string object. Don't use sizeof() either. Use .length().
std::string in C++ is instantiated as a pointer to a string object, since a string may have varying length. What sizeof() is returning is the size of the pointer to the string object (which on a 32 bit machine will probably be 4)
Operator sizeof() returns size of given type or object in bytes. 'Type version' is quite simple to understand, bu with 'Object version' you need to rember one thing:
sizeof() looks only on type definition and deduces total size from size and number of its members (in general, polymorphic and multiple inherited types may have additional 'hidden' members).
In other words, let's assume we have:
struct A
{
int* p1;
char* p2;
};
As you can probably suspect, sizeof(A) will return 8 (as pointer is 4-byte type on most 32-bit systems). But, when you do something like this:
A a_1;
a_1.p1 = new int[64];
sizeof(a_1) will still return 8. That's because memory allocated by new and pointed by A's member, does not 'belong' to this object.
And that is why sizeof(str) and str.length() give different results. std::string allocates memory for chars on the heap (dynamically, via malloc()), so it doesn't change string's size.
So, if you want to send string via network, proper size is str.len() and data pointer can be retrieved by calling str.c_str().
I didn't understant part with "strlen(str) equivalent". In C++ there is also strlen() function, with the same prototype, working exactly in the same way. It simply requires const char*, so you cannot use it for std::string (but you can do strlen(str.c_str()), as std::string's internal string is guaranteed to be null-terminated). For std::string use .length() as you already did.
The documentation says:
istream::get ( char* s, streamsize n, char delim );
// Extracts characters from the stream and stores them as a
// c-string into the array beginning at s
I tried to analyze what this function does. It takes a pointer "by value". That is it cannot allocate dynamic memory and set the pointer s to it. It can only change what the pointer s points to.
But if the function cannot perform dynamic memory allocation, how can it return an output whose length is not known? How should I use this function? Should I preallocate memory and pass the pointer to it as s and then delete it by myself?
The documentation is clear:
stores them as a c-string into the array beginning at s
– s has to point to a valid array that’s big enough to accommodate the read string.
how can it return an output whose length is not known
The maximum length is known, it’s n (actually n - 1, since one character is reserved for the null termination of the C string).
However, given your questions it’s probably more appropriate to use the std::string overload of getline.
You should preallocate memory (pointed to by s) of size n, pass that s to first and n to second parameter of the function. This way, get will read maximum n bytes (including terminating null) and copy them to buffer pointed to by s
If your buffer is local (an array on the stack, lets say), you don't have to delete it (in fact you can't) However if it is dynamic (i.e, allocated by new[], malloc, operator new or whatever) then you have to free it accordingly.
example:
const int n = 50;
char *s = new char[n];
cin.get(s, n);
//...
delete []s;
note: although this is valid, as others commented, better use std::string instead.
You should use it like this:
const int size = 10;
char s[size]; //large enough to fit string
stream.get(&s[0], size, '\n');
You preallocate the buffer you need and make sure it's large enough to fit target string.
I need to be able to set the size of an array based on the number of bytes in a file.
For example, I want to do this:
// Obtain the file size.
fseek (fp, 0, SEEK_END);
size_t file_size = ftell(fp);
rewind(fp);
// Create the buffer to hold the file contents.
char buff[file_size];
However, I get a compile time error saying that the size of the buffer has to be a constant.
How can I accomplish this?
Use a vector.
std::vector<char> buff(file_size);
The entire vector is filled with '\0' first, automatically. But the performance "lost" might not be noticable. It's certainly safer and more comfortable. Then access it like a usual array. You may even pass the pointer to the data to legacy C functions
legacy(&buff[0]); // valid!
You should use a std::vector and not an array.
Real arrays require you to specify their size so that the compiler can create some space for them -- this is why the compiler complains when you don't supply a constant integer. Dynamic arrays are represented by a pointer to the base of the array -- and you have to retrieve the memory for the dynamic array yourself. You may then use the pointer with subscript notation. e.g.,
int * x;
x = (int *) malloc( sizeof(int) *
getAmountOfArrayElements() /* non-const result*/
);
x[5] = 10;
This leads to two types of problems:
Buffer over/under flows : you might subscript-index past either end of the array.
You might forget to release the memory.
Vector provides a nice little interface to hide these problems from you -- if used correctly.
Replace
char buff[file_size];
with
char *buff = new char[file_size];
and once the use of the buff is done..you can free the memory using:
delete[] buff;
There are two points in your question I'd like to cover.
The actual question, how do you create the array. Johannes answered this. You use a std::vector and create it with a size allocation.
Your error message. When you declare an array of some type, you must declare it with a constant size. So for example
const int FileSize = 1000;
// stuff
char buffer[FileSize];
is perfectly legitimate.
On the other hand, what you did, attempting to declare an array with variable size, and then not allocating with new, generates an error.
Problem is that buff needs be created on the heap (instead of stack). Compiler want s to know the exact size to create on the stack.
char* buff = new char[file_size];
In C++, arrays cannot be passed simply as parameters. Meaning if I create a function like so:
void doSomething(char charArray[])
{
// if I want the array size
int size = sizeof(charArray);
// NO GOOD, will always get 4 (as in 4 bytes in the pointer)
}
I have no way of knowing how big the array is, since I have only a pointer to the array.
Which way do I have, without changing the method signature, to get the size of the array and iterate over it's data?
EDIT: just an addition regarding the solution. If the char array, specifically, was initialized like so:
char charArray[] = "i am a string";
then the \0 is already appended to the end of the array. In this case the answer (marked as accepted) works out of the box, so to speak.
Use templates. This technically doesn't fit your criteria, because it changes the signature, but calling code does not need to be modified.
void doSomething(char charArray[], size_t size)
{
// do stuff here
}
template<size_t N>
inline void doSomething(char (&charArray)[N])
{
doSomething(charArray, N);
}
This technique is used by Microsoft's Secure CRT functions and by STLSoft's array_proxy class template.
Without changing the signature? Append a sentinel element. For char arrays specifically, it could be the null-terminating '\0' which is used for standard C strings.
void doSomething(char charArray[])
{
char* p = charArray;
for (; *p != '\0'; ++p)
{
// if '\0' happens to be valid data for your app,
// then you can (maybe) use some other value as
// sentinel
}
int arraySize = p - charArray;
// now we know the array size, so we can do some thing
}
Of course, then your array itself cannot contain the sentinel element as content.
For other kinds of (i.e., non-char) arrays, it could be any value which is not legal data. If no such value exists, then this method does not work.
Moreover, this requires co-operation on the caller side. You really have to make sure that the caller reserves an array of arraySize + 1 elements, and always sets the sentinel element.
However, if you really cannot change the signature, your options are rather limited.
In general when working with C or low-level C++, you might consider retraining your brain to never consider writing array parameters to a function, because the C compiler will always treat them as pointers anyway. In essence, by typing those square brackets you are fooling yourself in thinking that a real array is being passed, complete with size information. In reality, in C you can only pass pointers. The function
void foo(char a[])
{
// Do something...
}
is, from the point of view of the C compiler, exactly equivalent to:
void foo(char * a)
{
// Do something
}
and obviously that nekkid char pointer contains no length information.
If you're stuck in a corner and can't change the function signature, consider using a length prefix as suggested above. A non-portable but compatible hack is to specify the array length in an size_t field located before the array, something like this:
void foo(char * a)
{
int cplusplus_len = reinterpret_cast<std::size_t *>(a)[-1];
int c_len = ((size_t *)a)[-1];
}
Obviously your caller needs to create the arrays in the appropriate way before passing them to foo.
Needless to say this is a horrible hack, but this trick can get out of trouble in a pinch.
It actually used to be a quite common solution to pass the length in the first element of the array. This kind of structure is often called BSTR (for “BASIC string”), even though this also denoted different (but similar) types.
The advantage over the accepted solution is that determining the length using a sentinel is slow for large strings. The disadvantage is obviously that this is a rather low-level hack that respects neither types nor structure.
In the form given below it also only works for strings of length <= 255. However, this can easily be expanded by storing the length in more than one byte.
void doSomething(char* charArray)
{
// Cast unnecessary but I prefer explicit type conversions.
std::size_t length = static_cast<std::size_t>(static_cast<unsigned char>(charArray[0]));
// … do something.
}
if it's nullterminated, strlen() would work.
You can't determine the size from charArray alone. That information is not automatically passed to the function.
Of course if it's a null-terminated string you can use strlen(), but you have probably considered that already!
Consider passing a std::vector<char> & parameter, or a pair of pointers, or a pointer plus a size parameter.
This is actually more C than C++, in C++ you'd probably rather use a std::vector. However, in C there's no way to know the size of an array. The compile will allow you to do a sizeof if the array was declared in the current scope, and only if it was explicitly declared with a size (EDIT: and "with a size", I mean that it was either declared with an integer size or initialized at declaration, as opposed to being passed as a parameter, thanks for the downvote).
The common solution in C is to pass a second parameter describing the number of elements in the array.
EDIT:
Sorry, missed the part about not wanting to change the method signature. Then there's no solution except as described by others as well, if there's some data that is not allowed within the array, it can be used as a terminator (0 in C-strings, -1 is also fairly common, but it depends on your actual data-type, assuming the char array is hypothetical)
In order for a function to know the number of items in an array that has been passed to it, you must do one of two things:
Pass in a size parameter
Put the size information in the array somehow.
You can do the latter in a few ways:
Terminate it with a NULL or some
other sentinel that won't occur in
normal data.
store the item count in the first entry if the array holds numbers
store a pointer to the last entry if the array contains pointers
try using strlen(charArray);
using the cstring header file. this will produce the number of characters including spaces till it reaches the closing ".
You are guarranteed to receive 4 in a 32-bit PC and that's the correct answer. because of the reason explained here and here.
The short answer is, you are actually testing the sizeof a pointer rather than an array, because "the array is implicitly converted, or decays, into a pointer. The pointer, alas, doesn't store the array's dimension; it doesn't even tell you that the variable in question is an array."
Now that you are using C++, boost::array is a better choice than raw arrays. Because it's an object, you won't loose the dimention info now.
I think you can do this:
size_t size = sizeof(array)/sizeof(array[0]);
PS: I think that the title of this topic isn't correct, too.
Dude you can have a global variable to store the size of the array which will be accessible throughout the program. At least you can pass the size of the array from the main() function to the global variable and you will not even have to change the method signature as the size will be available globally.
Please see example:
#include<...>
using namespace std;
int size; //global variable
//your code
void doSomething(char charArray[])
{
//size available
}