Cannot understand the first argument of write() - c++

I came across the statement:
outbal.write( (char*) &acc , sizeof( struct status ) );
outbal is an object of ofstream and status is a type.
Therefore:
struct status {
// code
};
status acc;
Talking about the second line I don't understand the first argument, which is (char*) &acc. What are we doing and how?

(char*)&acc if the address of the variable acc, cast to a char pointer so as to be compatible with ostream::write(). It is that variable that is being written, to the outbal stream, for a length of sizeof(struct status).
ostream::write takes a memory address and a length and will output that memory to the specified stream. In other words, you're simply outputting the entire memory contents of the acc variable.
Your code is similar to:
struct xyz {int a; float b; void *c};
ostream os("myfile.dat");
struct xyz abc; // 'struct' not technically needed in C++
os.write ( (char *)abc, sizeof (struct xyz));
// <<-memory addr->> <<-----size----->>

You are taking the address of acc and casting it to char*, which is what the ostream::write member function expects.
In short, you are writing the in-memory representation of the struct as-is to a stream.

(char*) &acc takes the address of the struct acc (i.e. a pointer to acc) and then casts it into a pointer to a char.

That's just taking the address of acc and casting it to a pointer to char.
Most likely that .write() method is meant to just blindly write a given amount of bytes out as-is. char is a convienent type to use for that, since (on most platforms) it is exactly one byte in size. So you pass it a pointer to the data you want written out, telling it, "Pretend this is a pointer to char".

Related

cast to pointer from integer of different size when converting uint64_t to bytes

[EDIT]I wanted write uint64_t to char* array in network byte order to send it as UDP datagram with sendto, uint64_t has 8 bytes so I convert them as follow:
void strcat_number(uint64_t v, char* datagram) {
uint64_t net_order = htobe64(v);
for (uint8_t i=0; i<8 ;++i) {
strcat(datagram, (const char*)((uint8_t*)&net_order)[i]);
}
}
wchich give me
warning: cast to pointer from integer of different size [-Wint-to-pointer-xast]
strcat(datagram, (const char*)((uint8_t*)&net_order)[i]);
how can I get rid of this warning or maybe do this number converting simpler or clearer?
((uint8_t*)&net_order)
this is a pointer to net_order casted to a uint8_t pointer
((uint8_t*)&net_order)[i]
this is the i-th byte of the underlying representation of net_order.
(const char*)((uint8_t*)&net_order)[i]
this is the same as above, but brutally casted to a const char *. This is an invalid pointer, and it is what the compiler is warning you about; even just creating this pointer is undefined behavior, and using it in any way will almost surely result in a crash.
Notice that, even if you somehow managed to make this kludge work, strcat is still the wrong function, as it deals with NUL-terminated strings, while here you are trying to put binary data inside your buffer, and binary data can naturally contain embedded NULs. strcat will append at the first NUL (and stop at the first NUL in the second parameter) instead of at the "real" end.
If you are building a buffer of binary data you have to use straight memcpy, and most importantly you cannot use string-related functions that rely on the final NUL to know where the string ends, but you have to keep track explicitly of how many bytes you used (i.e. the current position in the datagram).

C++ string length in bytes

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.

c++ cout uncasted memory (void)

This is the scenario;
// I have created a buffer
void *buffer = operator new(100)
/* later some data from a different buffer is put into the buffer at this pointer
by a function in an external header so I don't know what it's putting in there */
cout << buffer;
I want to print out the data that was put into the buffer at this pointer to see what went in. I would like to just print it out as raw ASCII, I know there will be some non-printable characters in there but I also know some legible text was pushed there.
From what I have read on the Internet cout can't print out uncasted data like a void, as opposed to an int or char. However, the compiler wont let me cast it on the fly using (char) for example. Should I create a seperate variable that casts the value at the pointer then cout that variable, or is there a way I can do this directly to save on another variable?
Do something like:
// C++11
std::array<char,100> buf;
// use std::vector<char> for a large or dynamic buffer size
// buf.data() will return a raw pointer suitable for functions
// expecting a void* or char*
// buf.size() returns the size of the buffer
for (char c : buf)
std::cout << (isprint(c) ? c : '.');
// C++98
std::vector<char> buf(100);
// The expression `buf.empty() ? NULL : &buf[0]`
// evaluates to a pointer suitable for functions expecting void* or char*
// The following struct needs to have external linkage
struct print_transform {
char operator() (char c) { return isprint(c) ? c : '.'; }
};
std::transform(buf.begin(), buf.end(),
std::ostream_iterator<char>(std::cout, ""),
print_transform());
Do this:
char* buffer = new char[100];
std::cout << buffer;
// at some point
delete[] buffer;
void* you only need in certain circumstances, mostly for interop with C interfaces, but this is definitely not a circumstance requiring a void*, which essentially loses all type information.
You need to cast it to char*: reinterpret_cast<char*>(buffer). The problem is that void* represents anything, so only th pointer is printed; when you cast it to char*, the contents of the memory are interpreted as a C-style string
Note: use reinterpret_cast<> instead of the C-style (char *) to make your intent clear and avoid subtle-and-hard-to-find bugs later
Note: of course you might get a segfault instead, as if the data is indeed not a C-style string, memory not associated with the buffer might be accessed
Update: You could allocate the memory to a char* buffer to begin with and it would solve your problem too: you could still call your 3rd party function (char* is implicitly convertible to void*, which I presume is the 3rd party function's parameter type) and you don't need to do the cast-ing at all. Your best bet is to zero-out the memory and restrict the 3rd party function to copy more than 99*sizeof(char) bytes into your buffer to preserve the ending '\0' C-style string terminator
If you want to go byte by byte you could use an unsigned char and iterate over it.
unsigned char* currByte = new unsigned char[100];
for(int i = 0; i < 100; ++i)
{
printf("| %02X |", currByte[i]);
}
It's not a very modern (or even very "C++") answer but it will print it as a hex value for you.

Typecasting argv to structure type

I have a structure defined as
struct xyz {
char *str;
int x;
int y;
};
Which I am getting as input parameter to the executable from some other program1.(other program did execve of the program2 with input parameter as this structure).
I wish to know, can I do the typecast of this input parameter as (struct xyz*)argv[1];, or I have to convert it to string format before sending it?
You can't pass arbitrary data to a command in that way. You'll have to serialize it to a string, or perform some IPC (e.g. through pipe/socket).
The reason for this is that the strings are null terminated. Your char* member will have a \0 on the end, and even if it doesn't, any int less than 16843009 (0x01010101) will have a null byte in it and fail to copy properly.
argv[1] is a string. You can't cast a string to a struct. You need to create your own wrapper functions to serialize and parse, and then watch out for all sorts of issues -- endian-ness issues and encoding issues (wide chars with Unicode, etc.)

Reading a cubin structure from a pointer

I am trying to read the contents a c++ structure(in windows) which has the following format
typedef struct __cudaFatCudaBinaryRec {
unsigned long magic;
unsigned long version;
unsigned long gpuInfoVersion;
char* key;
char* ident;
char* usageMode;
__cudaFatPtxEntry *ptx;
__cudaFatCubinEntry *cubin;
__cudaFatDebugEntry *debug;
void* debugInfo;
unsigned int flags;
__cudaFatSymbol *exported;
__cudaFatSymbol *imported;
struct __cudaFatCudaBinaryRec *dependends;
unsigned int characteristic;
__cudaFatElfEntry *elf;
} __cudaFatCudaBinary;
I have a pointer to this structure (void *ptr)
Now I am looking to read the contents of this structure.
__cudaFatCudaBinary *ptr2=(cudaFatCudaBinary*)ptr;
cout<<ptr->magic;//This works fine
cout<<ptr->key;//This crashes my program..bad pointer results..why?
The above is consistent with all non pointer and pointer members. What am I doing wrong?
ADDED:
ok let me elaborate on the problem. Yes, the address pointed to by "key" is NULL and so it is for all the pointer members. But I know for sure the structure has valid data. It is used by a driver function to generate a handle and it executes fine. All I need is to copy the entire image of the structure and store it in a text file. How would I do it? Why are some of the member fields null? I am thinking of a brute force way to find the address limits of the structure. But the values themselves seem to be invalid when read and I don't know how to go about it!
ADDED 2
Memory Dump of the structure
Thanks !
cout << ptr->key will print as a 0-terminated string whatever key points to, not the pointer itself. If key is NULL or otherwise invalid then this will be undefined behaviour. (In this case a "crash")
If you just want to print the pointer itself make sure you print it as a void* pointer:
cout << static_cast<void*>(ptr->key);
As of CUDA 4.0, the format of this struct drastically changed. The value of magic is now different and gpuInfoVersion is now a pointer to a struct that contains the actual data. For more information, you might want to read this thread.