Copy number of bytes to a position in memory - c++

If I am not correct, the codes following are used to copy an array of bytes to a position of memory in C#:
byte[] byteName = Encoding.ASCII.GetBytes("Hello There");
int positionMemory = getPosition();
Marshal.Copy(byteName, 0, new IntPtr(positionMemory), byteName.length);
How can I achieve this in native C++?

use a pointer and memcpy:
void * memcpy ( void * destination, const void * source, size_t num );
Suppose you want to copy an array A of length n into an array B
memcpy (B, A, n * sizeof(char));
This is more C than C++, the string class have copy capabilities you can use.
size_t length;
char buffer[20];
string str ("Test string...");
length=str.copy(buffer,6,5);
buffer[length]='\0';
Here's a more specific sample with a complete code:
#include <stdio.h>
#include <string>
#include <string.h>
#include <iostream>
using namespace std;
int main()
{
string s("Hello World");
char buffer [255];
void * p = buffer; // Or void * p = getPosition()
memcpy(p,s.c_str(),s.length()+1);
cout << s << endl;
cout << buffer << endl;
return 0;
}
let me know if you need more details

memcpy(), memmove(), CopyMemory(), and MoveMemory() can all be used as native equivilents of Marshal.Copy(). As for the position handling, all the .NET code is doing as casting the integer to a pointer, which you can do in C++ as well. The .NET code you showed is equivilent to the following:
std::string byteName = "Hello There";
int positionMemory = getPosition();
memcpy(reinterpret_cast<void*>(positionMemory), byteName.c_str(), byteName.length());

Related

cpp function returning garbage string value [duplicate]

I'm a newbie in C++ learning the language and playing around. I wrote a piece of code which behavior I don't understand. Could someone explain why the code below prints out random junk and not the first character of the first string in the list (that is a).
#include <iostream>
#include <vector>
#include <string>
#include <cstdlib>
#include <ctime>
#include <climits>
#include <stdio.h>
char* str2char(std::string str)
{
char cset[str.size()+1]; // +1 for the null character
for(int i = 0; i < str.size(); i++)
{
cset[i] = str[i];
}
cset[str.size()] = '\0';
return cset;
}
int main (int argc, char * const argv[]) {
std::vector< std::string > ladontakadet;
ladontakadet.push_back("aabcbbca");
ladontakadet.push_back("abcdabcd");
ladontakadet.push_back("cbbdcdaa");
ladontakadet.push_back("aadcbdca");
ladontakadet.push_back("cccbaaab");
ladontakadet.push_back("dabccbaa");
ladontakadet.push_back("ccbdcbad");
ladontakadet.push_back("bdcbccad");
ladontakadet.push_back("ddcadccb");
ladontakadet.push_back("baccddaa");
std::string v = ladontakadet.at(0);
char *r;
r = str2char(v);
std::cout << r[0] << std::endl;
return 0;
}
Why is my returning garbage, when I'm expecting it to output a?
Thnx for any help!
P.S. The output of this code is random. It doesn't always print the same character..:S
It's because you return a pointer to a local variable, a local variable that goes out of scope when the function returns.
You are already using std::string for the argument, use it instead of the array and the return pointer.
If your aim is to pass the content of a std::string to a function modifying the content of a char*:
#include <iostream>
#include <vector>
void f(char* s) {
s[0] = 'H';
}
std::vector<char> to_vector(const std::string& s) {
return std::vector<char>(s.c_str(), s.c_str() + s.size() + 1);
}
int main(void)
{
std::string s = "_ello";
std::vector<char> t = to_vector(s);
f(t.data());
std::cout << t.data() << std::endl;
}
Your function is returning garbage because you're returning the address of a local variable which goes out of scope after your function returns. It should probably look like this:
char* str2char(const std::string &str)
{
char *const cset = new char[str.size() + 1]; // +1 for the null character
strcpy(cset, str.c_str());
return cset;
}
You will need to delete your variable r by doing delete[] r;. Ideally though you wouldn't be using raw pointers, and you would use std::string for everything, or wrap the char * in a std::unique_ptr.

c++ : char* invariably stores the word vector

This is although a code specific question but the output is quite bizarre.
I am aware of STL string etc. I was fooling around when I noticed something strange, and could not find a reason for it. :(
See the Two Codes below and the output.
[Code #1] (https://ideone.com/ydB8sQ)
#include <iostream>
#include <vector>
#include <cstdlib>
#include <cstdio>
using namespace std;
class str
{
private:
vector<char> A;
public:
str(const char *S) {
int sz = sizeof(S);
cerr << sz << endl;
for (int i = 0; i < sz; ++i) {
cout << S[i];
//A.push_back(S[i]); //!-- Comment --!//
}
}
};
int main(int argc, char const *argv[])
{
str A("");
return 0;
}
In this, An Empty String is passed and is printed. The Vector A does nothing but is relevant to this problem. In the first version, A is untouched, and the code prints garbage value. (see ideone O/P)
In this second version ( see A.push_back is now uncommented )
[Code #2] (https://ideone.com/PPHGZy)
#include <iostream>
#include <vector>
#include <cstdlib>
#include <cstdio>
using namespace std;
class str
{
private:
vector<char> A;
public:
str(const char *S) {
int sz = sizeof(S);
cerr << sz << endl;
for (int i = 0; i < sz; ++i) {
cout << S[i];
A.push_back(S[i]);
}
}
};
int main(int argc, char const *argv[])
{
str A("G");
return 0;
}
The Output is :
Gvector
This is across GCC / MinGW x64. This one never prints garbage value but always contains the word 'vector'.
Where is the char* in the function pointing to?
Why would 'vector' be there anyways?
Also, the size of char * is 8.
EDIT : This does not happen if it isn't wrapped around a 'class'.
The word 'vector' appears always. I supposed it was random garbage value but then how come ideone still has the same word in its memory?
The main problem in your code is in line int sz = sizeof(S);. sizeof(S) is always equal to sizeof(char *) which seems to be 8 on your system. sizeof gives you number of bytes for variable itself. If you want to know number of bytes in string to which your char pointer points, you should use strlen function instead.
You get that vector string in output randomly, as you are accessing memory which is not in allocated space. Accessing such memory is undefined behavior, so you get your undefined result.

Initialize const char * with out any memory leaks

Below is my sample code. Its just a sample which is similar to the code which i'm using in my applicaiton.
#define STR_SIZE 32
void someThirdPartyFunc(const char* someStr);
void getString(int Num, const char* myStr)
{
char tempStr[] = "MyTempString=";
int size = strlen(tempStr) + 2;
snprintf((char*)myStr, size, "%s%d", tempStr, Num);
}
int main()
{
const char * myStr = new char(STR_SIZE);
getString(1, myStr); // get the formated string by sending the number
someThirdPartyFunc(myStr); // send the string to the thirdpartyFunction
delete myStr;
return 0;
}
I am getting an exception if i use this code. I think the problem is with deleting the "myStr". But delete is really necessary.
Is there any other way to format the string in getString and send it to the ThirdPartyFunc??
Thanks in advance.
you are allocating not an array of chars but one char with this line:
const char * myStr = new char(STR_SIZE);
and that one allocated char is initialized with the value of STR_SIZE, causing a "char overflow" in this case.
if you want an array of size STR_SIZE:
const char * myStr = new char[STR_SIZE];
(note the rectangular [ ]). you have to deallocate such allocated chunk of memory by using the delete[] operator.
personal note: the code you have written above (manually allocated strings etc) is good educational wise; you will do a lot of such mistakes and thus learn about the inner workings of C / C++. for production code you do not want that, for production code you want std::string or other string-containers to avoid repeating string-related mistakes. in general you are not the one who sucessfully reinvent how string-libraries will work. the same is true for other container-types like dynamically-growable-arrays (std::vector) or dictionary-types or whatever. but for educational fiddling around your code above serves a good purpose.
there are other problems in your code snippet (handing over const char* to a function and then modifying the ram, not calculating correctly the size parameter when calling snprintf etc), but these are not related to your segfault-problem.
Re the technical, instead of
const char * myStr = new char(STR_SIZE);
do
char const myStr[STR_SIZE] = "";
Note that both have the problem that the string can’t be modified.
But you only asked about the allocation/deallocation problem.
But then, there's so much wrong at levels above the language-technical.
Here's the original code, complete:
void someThirdPartyFunc(const char* someStr);
void getString(int Num, const char* myStr)
{
char tempStr[] = "MyTempString=";
int size = strlen(tempStr) + 2;
snprintf((char*)myStr, size, "%s%d", tempStr, Num);
}
int main()
{
const char * myStr = new char(STR_SIZE);
getString(1, myStr); // get the formated string by sending the number
someThirdPartyFunc(myStr); // send the string to the thirdpartyFunction
delete myStr;
return 0;
}
Here's how to do that at the C++ level:
#include <string> // std::string
#include <sstream> // std::ostringstream
using namespace std;
void someThirdPartyFunc( char const* ) {}
string getString( int const num )
{
ostringstream stream;
stream << "MyTempString=" << num;
return stream.str();
}
int main()
{
someThirdPartyFunc( getString( 1 ).c_str() );
}
The #define disappeared out of the more natural code, but note that it can very easily lead to undesired text substitutions, even with all uppercase macro names. And shouting all uppercase is an eyesore anyway (which is why it's the macro name convention, as opposed to some other convention). In C++ simply use const instead.

Converting to uppercase in C++

Let's say you have:
const char * something = "m";
How would one make this uppercase, using toupper (or something else, if applicable)?
I want to use a char * instead of a string (I can use a string, but then I have to use str.c_str()).
So, how can I make char * something = "m"; contain "M"?
I find you choice of C strings disturbing.. but anyway.
You can't change a string literal (char *something). Try an array:
char something[] = "m";
something[0] = toupper(something[0]);
To change an entire string:
char something[] = "hello";
char *p = something;
while (*p) {
*p = toupper(*p);
p++;
}
As explained in the very famous C book - The C Programming Language by Kernighan & Ritchie in section 5.5 Character Pointers and Functions,
char amessage[] = "now is the time"; /* an array */
char *pmessage = "now is the time"; /* a pointer */
`amessage` is an array, just big enough to hold the
sequence of characters and `'\0'` that initializes it.
Individual characters within the array may be changed
but `amessage` will always refer to the same storage.
On the other hand, `pmessage` is a pointer, initialized
to point to a string constant; the pointer may subsequently
be modified to point elsewhere, but the result is undefined
if you try to modify the string contents.
OTOH, in C, to convert to upper case letters, you can use the following program as a reference.
#include <stdio.h>
#include <ctype.h>
int main(void)
{
int i=0;
char str[]="Test String.\n";
char c;
while (str[i]) {
c=str[i];
putchar(toupper(c));
i++;
}
return 0;
}
In C++
#include <iostream>
#include <string>
#include <locale>
using namespace std;
int main ()
{
locale loc;
string str="Test String.\n";
for (size_t i=0; i<str.length(); ++i)
cout << toupper(str[i],loc);
return 0;
}
EDIT: Adding pointer version (as requested by #John) for the C version
#include <stdio.h>
#include <ctype.h>
int main(void)
{
int i=0;
char str[]="Test String.\n";
char *ptr = str;
while (*ptr) {
putchar(toupper(*ptr));
ptr++;
}
return 0;
}
Hope it helps!
You can use the same algorithmic approach that you know for std::string for raw arrays:
char s[] = "hello world";
std::transform(s, s + std::strlen(s), s, static_cast<int(*)(int)>(std::toupper));
You cannot do this for immutable string literals (like const char * s = "hello world;") for obvious reasons, so you won't get around an additional allocation/copy for that.
Update: As Ildjarn says in the comment, it's important to note that string literals are always read-only, even though for historical reasons you are allowed to bind them to a pointer-to-mutable, like char * s = "hello world";. Any decent C++ compiler should slap you in the face if you attempt this, but it is valid C++ -- but any attempt to actually modify any element of s is undefined behaviour.
You can convert C-string to std::string and then use boost::to_upper to change string in place or boost::to_upper_copy to create upper case copy of the string. Here is the code example:
#include <iostream>
#include <boost/algorithm/string/case_conv.hpp>
int main ()
{
char const * s = "Test String.\n";
std::string str(s);
std::cout << boost::to_upper_copy(str).c_str() << std::endl;
return 0;
}
Hope this helps.
You could do:
#include <algorithm>
#include <iterator>
#include <ctype.h>
char test[] = "m";
std::transform(std::begin(test), std::end(test), std::begin(test), ::topper);
This applies the ::toupper function to character of the string. This is the ::toupper function in the global namespace that comes from C. std::toupper has multiple overloads and ::toupper looks more elegant than static_cast<int (*)(int)>(&std::toupper).

iconv only works once

I try to make method which converts s-jis string to utf-8 string using iconv.
I wrote a code below,
#include <iconv.h>
#include <iostream>
#include <stdio.h>
using namespace std;
#define BUF_SIZE 1024
size_t z = (size_t) BUF_SIZE-1;
bool sjis2utf8( char* text_sjis, char* text_utf8 )
{
iconv_t ic;
ic = iconv_open("UTF8", "SJIS"); // sjis->utf8
iconv(ic , &text_sjis, &z, &text_utf8, &z);
iconv_close(ic);
return true;
}
int main(void)
{
char hello[BUF_SIZE] = "hello";
char bye[BUF_SIZE] = "bye";
char tmp[BUF_SIZE] = "something else";
sjis2utf8(hello, tmp);
cout << tmp << endl;
sjis2utf8(bye, tmp);
cout << tmp << endl;
}
and, output should be
hello
bye
but in fact,
hello
hello
Does anyone know why this phenomenon occurs? What's wrong with my program?
Note that "hello" and "bye" are Japanese s-jis strings in my original program, but I altered it to make program easy to see.
I think you are misusing the iconv function by passing it the global variable z. The first time you call sjis2utf8, z is decremented to 0. The second call to sjis2utf8 have no effect (z==0) and leaves tmp unchanged.
From the iconv documentation :
size_t iconv (iconv_t cd,
const char* * inbuf, size_t * inbytesleft,
char* * outbuf, size_t * outbytesleft);
The iconv function converts one multibyte character at a time, and for each character conversion it increments *inbuf and decrements *inbytesleft by the number of converted input bytes, it increments *outbuf and decrements *outbytesleft by the number of converted output bytes, and it updates the conversion state contained in cd.
You should use two separate variables for the buffers lengths :
size_t il = BUF_SIZE - 1 ;
size_t ol = BUF_SIZE - 1 ;
iconv(ic, &text_sjis, &il, &text_utf8, &ol) ;
Then check the return value of iconv and the buffers lengths for the conversion success.
#include <iconv.h>
#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
const size_t BUF_SIZE=1024;
class IConv {
iconv_t ic_;
public:
IConv(const char* to, const char* from)
: ic_(iconv_open(to,from)) { }
~IConv() { iconv_close(ic_); }
bool convert(char* input, char* output, size_t& out_size) {
size_t inbufsize = strlen(input)+1;// s-jis string should be null terminated,
// if s-jis is not null terminated or it has
// multiple byte chars with null in them this
// will not work, or to provide in other way
// input buffer length....
return iconv(ic_, &input, &inbufsize, &output, &out_size);
}
};
int main(void)
{
char hello[BUF_SIZE] = "hello";
char bye[BUF_SIZE] = "bye";
char tmp[BUF_SIZE] = "something else";
IConv ic("UTF8","SJIS");
size_t outsize = BUF_SIZE;//you will need it
ic.convert(hello, tmp, outsize);
cout << tmp << endl;
outsize = BUF_SIZE;
ic.convert(bye, tmp, outsize);
cout << tmp << endl;
}
based on Kleist's answer
You must put length of entry string in third parameter of iconv.
Try:
//...
int len = strlen(text_sjis);
iconv(ic , &text_sjis, &len, &text_utf8, &z);
//...
size_t iconv (iconv_t cd,
const char* * inbuf, size_t * inbytesleft,
char* * outbuf, size_t * outbytesleft);
iconv changes the value pointed to by inbytesleft. So after your first run z is 0. To fix this you should use calculate the length of inbuf and store it in a local variable before each conversion.
It is described here: http://www.gnu.org/s/libiconv/documentation/libiconv/iconv.3.html
And since you tagged this as C++ I would suggest wrapping everything up in a nice little class, as far as I can tell from the documentation you can reuse the inconv_t gained from iconv_open for as many conversions as you'd like.
#include <iconv.h>
#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
const size_t BUF_SIZE = 1024;
size_t z = (size_t) BUF_SIZE-1;
class IConv {
iconv_t ic_;
public:
IConv(const char* to, const char* from)
: ic_(iconv_open(to,from)) { }
~IConv() { iconv_close(ic_); }
bool convert(char* input, char* output, size_t outbufsize) {
size_t inbufsize = strlen(input);
return iconv(ic_, &input, &inbufsize, &output, &outbufsize);
}
};
int main(void)
{
char hello[BUF_SIZE] = "hello";
char bye[BUF_SIZE] = "bye";
char tmp[BUF_SIZE] = "something else";
IConv ic("UTF8","SJIS");
ic.convert(hello, tmp, BUF_SIZE);
cout << tmp << endl;
ic.convert(bye, tmp, BUF_SIZE);
cout << tmp << endl;
}