Passing char array to function - c++

I have to call a method with the following signature:
int sendTo(const void* buffer, int length, const SocketAddress& address, int flags=0);
My first question is:
What does const void* buffer exactly mean? My intention is: it means that it is a constant (unmodifiable) pointer which can point to anything. ist this somehow right?
Second question:
The purpose of this method is, obviously, to send data over a socket.
The first parameter is the data, the second is the length of that data.
If I want to pass the string "hello" as the first parameter, how would I do this?
My idea:
char hello_str[1024] = "hello"
socket.sendTo(hello_str, sizeof(hello_str),.....);
would this work? But this way I have a way too big char array.
How can I create the array with the right size?

Recall that const protect its left side unless there's nothing to it's left, then it protects its right side. Applying this to your code we'll get that const is protecting void* buffer. That means that the value it points to cannot be modified:
The first is a pointer to a const variable - The pointer can be changed.
The second is a const pointer to a variable - The value can be changed.
This will work, you can easily try it.
And as others already answered, creating it with the right size is done simply by:
char hello_str[] = "hello";

it means that it is a constant (unmodifiable) pointer which can point to anything
No, that would be void *const. It's rather a pointer-to-anything, where the pointee (the "anything" itself) can't be modified.
would this work?
yes, apart from the missing semi-colon.
How can i create the array with the right size?
char hello_str[] = "hello";
or even
const char hello_str[] = "hello";

First question: H2C03 is right, you should make the type be void * const to prevent the pointer from being modified.
Second question: You have some options here, depending on exactly what you are doing. Here are two examples that would work:
char hello_str[] = "hello"
socket.sendTo(hello_str, sizeof(hello_str)-1,...);
socket.sendTo(hello_str, strlen(hello_str),...);
In the first call to sendto, we are calculating the size of the string at compile time. We subtract 1 in order to avoid sending the null termination character at the end of the string. In the second case, we are computing it at runtime by calling the standard strlen function which is available in C and C++.

What does const void* buffer exactly mean?
It's an untyped pointer (that's another way of saying that it can point to anything). The value it points to cannot be modified (that's not entirely correct, but at least that is what you should think when you see that). The pointer itself can change however:
const void * buffer = &a;
buffer = &b; // this is valid!
Besides that, your function call is completely correct.

You can do :
const char hello_str[] = "hello"; // Don't forget the const
socket.sendTo(hello_str, sizeof(hello_str)-1,.....);
// or socket.sendTo(hello_str, strlen(hello_str),.....);
To answer to your questions :
What does const void* buffer exactly mean? My intention is: it means that it is a constant (unmodifiable) pointer which can point to anything. ist this somehow right?
No, That would be void* const. const void* means that it is the pointee that cannot be modified.
You may read this.

Related

Difference between * and & when passing a string to any function?

This is a simple operator overloading program I learned and I can't understand exactly why the parameterized constructor is using '*st' and not just 'st' or '&st'.
Now, I know the difference between passing by reference, address and value.
In the given example, I passed a string. If it was passing by reference, the argument in the parameterized constructor would have been '&st'. I'm not sure if it is passing the string by address.
Basically, I don't know how the code is working there. Please explain that and also why using '&st' in place of '*st' isn't working.
class tyst
{
int l;
char *p;
public:
tyst(){l=0;p=0;}
tyst(char *st)
{
l=strlen(st);
p = new char[l];
strcpy(p,st);
}
void lay();
tyst operator + (tyst b);
};
void tyst::lay()
{
cout<<p<<endl;
}
tyst tyst::operator+(tyst b)
{
tyst temp;
temp.l=l+b.l;
temp.p = new char[temp.l];
strcpy(temp.p,p);
strcat(temp.p,b.p);
return temp;
}
int main()
{
tyst s1("Markus Pear");
tyst s2("son Notch");
tyst s3;
s3=s1+s2;
s3.lay();
return 0;
}
So, I'd really appreciate if anyone can clear this up for me.
st is a C-style string. Passed by value
tyst(char st)
you would merely get a single character.
Passed by reference
tyst(char & st)
You would also get only a single character, but you could modify it. Not so useful in this case. You could also pass in a reference to a pointer, but I don't see much use to that, either.
How this is working
tyst(char * st)
says that the function will take a pointer, and that pointer may be pointing to a single character, the first of an unknown number of characters, absolutely nothing, or complete garbage. The last two possibilities are why use of references is preferred over pointers, but you can't use a reference for this. You could however use a std::string. In C++, this would often be the preferred approach.
Inside tyst, the assumption that an unknown, but null-terminated, number of characters is pointed at, and this is almost what is being provided. Technically, what you are doing here with
tyst s1("Markus Pear");
is illegal. "Markus Pear" is a string literal. It may be stored in non-writeable memory, so it is a const char *, not a char *.
The constructor is expecting a pointer to a c-string (null terminated character array). Applying pointer arithmetic to it will allow access to the entire string. Note that new[] returns a pointer to the first element; it is (one way) how pointers are used.
Aside from the syntax errors, it makes no sense to pass a single character by reference to the class. It isn't interested in a single character, it is interested in where the beginning of the array is.
It would be like asking somebody what their home address is, and they give you a rock from their lawn.

How to use strtof endPointer?

Looking at the examples presented by various google results, I don't really understand how the EndPtr works. For an example:
char szOrbits[] = "686.97 365.24";
char* pEnd;
float f1 = strtof (szOrbits, &pEnd);
The function takes the pointer of the pointer that is declared after the char array, does that mean that the actual type and contents of the pointer are irrelevant and the pointer is guaranteed to be allocated right after the array thus making its address the end point?
I tried using it like this:
ret.push_back(EquationPiece(strtof(&Source[mark], (char**)&Source[i])));
where ret is a vector, Source is a char array, mark is where the number begins and i is the next byte after the number but I'm getting some strange results. Is my usage incorrect or should I seek for the bug elsewhere?
Although the reference page describes the parameter pendptr as a reference to a char* object this might be misundestood. In C we have only pointers and the second parameter of strtof is a pointer to a pointer to char.
You can utilize this parameter to get the point in the input char array that could not be used to convert the char array to the output float. If the pointer points to a '\0' than the array has been converted entirely. If it points to something different you can start error handling or further processing of the char array.
You should never cast any pointer when you are not sure what it means. Cast tells the compiler that the programmer knows it better. Depending on the meaning of your EquationPiece it might be useful to pass the endPtr:
ret.push_back(EquationPiece(strtof(&Source[mark], pEnd));

Passing in and modifying an array in a function

I have been looking at other posts and trying to get this working for a bit, but can't seem to manage it.
Basically I want to pass a "char myArray[10]" though into a function, have the function assign the values and then hand it back. It generally looks like this at the moment:
int MyClass::GetArray(char array[10])
{
char p[10];
... // a value is assigned to p
memcpy(&array, &p, sizeof(p)); // Here array ends up being 0x3232323232323232 <Error reading characters of string.>
return 0;
}
Called with:
char array[10];
myclass.GetArray(array);
So, I assume I need to pass the array through as a reference to the array[10] created before calling the function. But for that I am unsure how to create a pointer to a fixed array without making it either a general char* pointer or a pointer to an array of chars.
Secondly is the memcpy error (in the code comments above). I'm not sure if that is related or not though.
Then thing is that when you pass an array to a function, it decays to a pointer. So when you use the address-of operator & on array in the function, you're taking the address of the pointer, meaning you get a pointer to a pointer.
That, by the way, leads to undefined behavior.
Other than that it's all okay, you don't have to pass the array (or rather, pointer) by reference. It's just not very... C++-ish. :)

When to use const char * and when to use const char []

I know they are different, I know how they are different and I read all questions I could find regarding char* vs char[]
But all those answers never tell when they should be used.
So my question is:
When do you use
const char *text = "text";
and when do you use
const char text[] = "text";
Is there any guideline or rule?
As an example, which one is better:
void withPointer()
{
const char *sz = "hello";
std::cout << sz << std::endl;
}
void withArray()
{
const char sz[] = "hello";
std::cout << sz << std::endl;
}
(I know std::string is also an option but I specifically want to know about char pointer/array)
Both are distinctly different, For a start:
The First creates a pointer.
The second creates an array.
Read on for more detailed explanation:
The Array version:
char text[] = "text";
Creates an array that is large enough to hold the string literal "text", including its NULL terminator. The array text is initialized with the string literal "text".The array can be modified at a later time. Also, the array's size is known even at compile time, so sizeof operator can be used to determine its size.
The pointer version:
char *text = "text";
Creates a pointer to point to a string literal "text". This is faster than the array version, but string pointed by the pointer should not be changed, because it is located in an read only implementation defined memory. Modifying such an string literal results in Undefined Behavior.
In fact C++03 deprecates use of string literal without the const keyword. So the declaration should be:
const char*text = "text";
Also,you need to use the strlen() function, and not sizeof to find size of the string since the sizeof operator will just give you the size of the pointer variable.
Which version is better?
Depends on the Usage.
If you do not need to make any changes to the string, use the pointer version.
If you intend to change the data, use the array version.
EDIT: It was just brought to my notice(in comments) that the OP seeks difference between:
const char text[] and const char* text
Well the above differing points still apply except the one regarding modifying the string literal. With the const qualifier the array test is now an array containing elements of the type const char which implies they cannot be modified.
Given that, I would choose the array version over the pointer version because the pointer can be(by mistake)easily reseated to another pointer and the string could be modified through that another pointer resulting in an UB.
Probably the biggest difference is that you cannot use the sizeof operator with the pointer to get the size of the buffer begin pointed to, where-as with the const char[] version you can use sizeof on the array variable to get the memory footprint size of the array in bytes. So it really depends on what you're wanting to-do with the pointer or buffer, and how you want to use it.
For instance, doing:
void withPointer()
{
const char *sz = "hello";
std::cout << sizeof(sz) << std::endl;
}
void withArray()
{
const char sz[] = "hello";
std::cout << sizeof(sz) << std::endl;
}
will give you very different answers.
In general to answer these types of questions, use the one that's most explicit.
In this case, const char[] wins because it contains more detailed information about the data within -- namely, the size of the buffer.
Just a note:
I'd make it static const char sz[] = "hello";. Declaring as such has the nice advantage of making changes to that constant string crash the program by writing to read-only memory. Without static, casting away constness and then changing the content may go unnoticed.
Also, the static lets the array simply lie in the constant data section instead of being created on the stack and copied from the constant data section each time the function is called.
If you use an array, then the data is initialized at runtime. If you use the pointer, the run-time overhead is (probably) less because only the pointer needs to be initialized. (If the data is smaller than the size of a pointer, then the run-time initialization of the data is less than the initialization of the pointer.) So, if you have enough data that it matters and you care about the run-time cost of the initialization, you should use a pointer. You should almost never care about those details.
I was helped a lot by Ulrich Drepper's blog-entries a couple of years ago:
so close but no cigar and more array fun
The gist of the blog is that const char[] should be preferred but only as global or static variable.
Using a pointer const char* has as disadvantages:
An additional variable
pointer is writable
an extra indirection
accessing the string through the pointer require 2 memory-loads
Just to mention one minor point that the expression:
const char chararr[4] = {'t', 'e', 'x', 't'};
Is another way to initialize the array with exactly 4 char.

c++ Final constant strings

In Java, we can specify a string as final to declare 'constants'. For example
static final String myConst = "Hello";
Is the correct way to do this in c++ like this?
const char * const myConst = "Hello";
I've always seen people do this:
const char * myConst = "Hello";
But, actually, you can change what that pointer points to. So, why do people not declare the pointer as constant as well? What is the correct way to do it?
const std::string myConst("Hello");
Yes, const char* const is the correct way to declare a C-style string which you will not change.
Or better:
#include <string>
const std::string myConst = "Hello";
const char * myConst = "Hello";
This means the object pointed at cannot change.
char * const myConst = "Hello";
This means the location pointed at by the pointer cannot change, but the object's value can.
const char * const myConst = "Hello";
This means neither may change. In my experience no one remembers this, but it's always available on the net!
Typical, three people answer in the time I write mine!
I don't exactly understand your question. To more or less mimic the final Java keyword, it would be either
const char * const myConst = "Hello";
(if the pointer is not going to change), and/or:
const char * myConst = "Hello";
if the pointer may change afterwards. Finally, note that with the first version, you cannot actually change the pointer itself, because it is constant.
With Diego's edit, yes, that the right way to write it. People typically don't declare the variable const because they don't care whether it will be modified, or, rather, trust that it won't be modified (since they know they don't modify it).
They declare the pointed-to const because a string literal really has const characters, so you really must assign it to a variable that has char const * values.
Technically,
char * const myConst = "Hello";
is the most correct answer, as reassigning the pointer would leave you with a string which probably could not be recovered.
Some implementations allow you to change the characters in "Hello" (even if it's a bad idea), so the first const in
char const * const myConst = "Hello";
Is a great idea. Personally as
char const * myConst = ...;
and
const char * myCount = ...;
are equivalent, I tend to enforce a style guideline that the const always follows the item it modifies. It sometimes reduces misconceptions in the long run.
That said, most people don't know how to use const correctly in C++, so it's either used poorly or not at all. That's because they just use C++ as an improved C compiler.
But, actually, you can change what
that pointer points to. So, why do
people not declare the pointer as
constant as well? What is the correct
way to do it?
Because it's rarely useful, more often than not you would want to have the values on the stack (pointers included) to be non-const. Get Sutter & Alexandrescu "Coding Standards" book, it explains this point.
The real point is that programmers are compeled to declare some pointers at least as const char * to store char arrays between double quotes. Nothing force them (no compiler warning or error) to also make the pointer constant... as people are lazy you can draw your own conclusion. They are probably not even really trying to define a constant, they just want to shut off compiler errors (well, warning in this case).
Keeping that in mind, I would probably go for a different solution anyway:
const char myConst[] = "Hello";
The difference here is that this way I won't decay the original byte array used as string to a pointer, I will still have a byte array that can be used exactly as the original literal.
With it I can do things like sizeof(myConst) and get the same result as with sizeof("Hello"). If I change string to a pointer, sizeof would return the size of a pointer, not the size of the string...
... and obviously when doing things this way changing the pointer becomes meaningless, as there is no pointer to change anymore.