the best way to keep a pointer in main changes reflected inside the class?
static unsigned char tmp[][20] = {"hello world", "bye world"};
class X {
unsigned char ** buffer;
public:
X(unsigned char* buff)
{
buffer = &buff;
}
void printThis()
{
DBG_MSG_FORMATED(".......> %s", *buffer);
}
};
int main (int argc, char * const argv[]) {
unsigned char * buff = new unsigned char[20];
memcpy(buff, tmp[0], 12);
X x(buff);
x.printThis();
memcpy(buff, tmp[1], 12);
x.printThis();
delete [] buff;
return EXIT_SUCCESS;
}
this works, but when I do the follow
buff = tmp[0];
x.printThis();
the printout doesnt print hello world again??? how to fix that
You'll need to use a pointer to pointer in your class (gulp!):
class X {
unsigned char ** buffer;
public:
X(unsigned char** buff)
{
buffer = buff;
}
void printThis()
{
DBG_MSG_FORMATED(".......> %s", *buffer);
}
};
And then pass in the address of the pointer during construction:
X x(&buff);
int main (int argc, char * const argv[]) {
unsigned char * buff = new unsigned char[20];
memcpy(buff, tmp[0], 12);
X x(buff);
x.printThis();
delete [] buff;
buff = tmp[1];
x.printThis();
return EXIT_SUCCESS;
}
After you have done delete buff;, your pointer buffer in the class is pointing at memory that has been deleted, which is very bad news.
If you want to store the actual address of buff, you would need to pass the address of buff and store that, like this:
char **buffer;
X(unsigned char** buff)
{
buffer = buff;
}
void printThis()
{
DBG_MSG_FORMATED(".......> %s", *buffer);
}
...
X x(&buff);
Or you could make buffer a reference to buff:
char*& buffer;
X(unsigned char*& buff) : buffer(buff) {}
(No other changes needed in class or other code - but note that you can't do buffer = some_other_buffer; at a later stage - that will change the value of buff to some_other_buffer, which is probably not what you expected).
You can do something thing as bellow (using a pointer to a pointer), but sincerally, this more a problem than a solution because you are unable to delete tmp without a good care with the pointer in class X
#include <cstdio>
#include <cstring>
static unsigned char tmp[][20] = {"hello world", "bye world"};
class X {
unsigned char ** buffer;
public:
X(unsigned char** buff)
{
buffer = buff;
}
void printThis()
{
printf(".......> %s", *buffer);
}
};
int main (int argc, char * const argv[]) {
unsigned char * buff = new unsigned char[20];
memcpy(buff, tmp[0], 12);
X x(&buff);
x.printThis();
buff = NULL;
buff = tmp[1];
x.printThis();
}
Related
I want to pass a string (char *) to a function inside a dll to overwrite it with another string.
File dll.cpp
__declspec(dllexport) void getString(char *name, char *buffer, int len) {
std::string str = getString(); // buffer should be overwritten with this string
char *cstr = new char[str.length() + 1];
strcpy(cstr, str.c_str());
strncpy(buffer, cstr, len);
}
File main.cpp
char *buffer;
getString("z", buffer, 128);
printf("%s", buffer);
I dont know how to correctly pass the buffer to overwrite it.
It's pretty clear you're confused about pointers. It looks like your use of cstr is at attempt to give buffer some memory, but that won't work and cstr is unnecessary.
Here's the correct code, buffer is allocated in main, and cstr is eliminated.
char *buffer = new char[128];
getString("z", buffer, 128);
printf("%s", buffer);
__declspec(dllexport) void getString(char *name, char *buffer, int len)
{
std::string str = getString();
strncpy(buffer, str.c_str(), len);
}
Note that strncpy is a dangerous function to use as it doesn't guarantee that the output is nul terminated. I would prefer to see code like this
__declspec(dllexport) void getString(char *name, char *buffer, int len)
{
if (len == 0)
{
// some kind of error handling
}
std::string str = getString();
strncpy(buffer, str.c_str(), len - 1);
buffer[len - 1] = '\0';
}
I'm trying to use a std::ostream backed by a buffer that I own.
When using setp to have the std::basic_streambuf to us my buffer, everything works fine expect that I would have expected the eof to be set when writing more bytes that were allocated for my buffer. The fail and bad bits are being set while the eof bit is not.
Is this the expected behavior?
If not, how can I get the eof bit to be set?
#include <iostream>
#include <streambuf>
template <typename char_type>
struct OStreamBufWrapper : public std::basic_streambuf<char_type, std::char_traits<char_type> >
{
OStreamBufWrapper(char_type* buffer, std::streamsize bufferLength)
{
// set the "put" pointer the start of the buffer and record its length.
this->setp(buffer, buffer + bufferLength);
}
};
int main(int argc, const char * argv[])
{
int bufsize = 10;
char *buf = new char[bufsize];
OStreamBufWrapper<char> ost(buf, bufsize);
std::ostream sb(&ost);
char i = 0;
while ( 1 )
{
sb.write(&i, 1);
if (!sb.good())
{
if (sb.fail())
std::cout << "fail\n";
if (sb.bad())
std::cout << "bad\n";
if (sb.eof())
std::cout << "eof\n";
break;
}
i++;
}
delete [] buf;
return 0;
}
I want to write a simple function to swap bytes in a QByteArray. This is what I have come up with:
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QString t = "abcde";
QByteArray test;
test.append(t.at(0));
test.append(t.at(1));
test.append(t.at(2));
test.append(t.at(3));
test.append(t.at(4));
qDebug() << t;
qDebug() << QString(swapBytes(test,0,3));
return a.exec();
}
QByteArray swapBytes(QByteArray in, int swapOffset, int quantity) {
if (swapOffset < 0) {
return in;
}
if(quantity>(in.length()/2)) {quantity=in.length()/2;}
if(quantity < 1) {quantity=1;}
int k;
char buf[quantity];
char buf2[quantity];
qDebug() << quantity;
for (int i = 0; i + quantity*2 + swapOffset <= in.length(); i=i+2*quantity) {
k=i;
for(int b = 0;b<i+quantity;b++){
buf[b]=in.at(k);
buf2[b]=in.at(k+swapOffset+quantity);
k++;
}
qDebug() << buf;
qDebug() << buf2;
qDebug() << in;
in.replace(0,quantity,buf2);
qDebug() << in;
in.replace(quantity+swapOffset,quantity,buf);
}
return in;
}
For some reason when I run this code I get the following output :
abcde
ab(
cd
abcde
cdcde
cdab(e
Where does the parentheses come from? As far as I know there is only one char per byte, so what is wrong?
You need to allocate one byte more than quantity to leave room for the null terminator. Try this:
char* buf = new char[quantity+1];
char* buf2 = new char[quantity+1];
memset(buf, 0, quantity+1);
memset(buf2, 0, quantity+2);
Then before your function returns, remember to deallocate:
delete [] buf;
delete [] buf2;
return in;
Alternately, you can just use a QByteArray in place of a char array:
QByteArray buf(quantity, 0x00);
QByteArray buf2(quantity, 0x00);
This allows you to skip calls to memset and to avoid worrying about deallocation.
Unrelated to all of this, note that you can initialize a QByteArray from a QString like this:
QByteArray test = t.toAscii();
I was making a re-creation of some System.IO functions from that class.
When I setup a buffer and allocate n number of bytes it'll read bytes to that and then add random bytes to the end of that buffer.
For example:
My Main:
int main(int argc, char *args[])
{
SetConsoleTitle(TEXT("Stream Test."));
cout<<"Press any Key to begin reading.";
cin.get();
const char* data = File::ReadAllBytes(args[1]);
Stream* stream = new Stream(data);
char* magic = new char[8];
stream->Read(magic, 0, 8);
magic[8] = '\0';
cout<<magic<<endl<<endl;
delete[]data;
cout<<"Press any key to quit.";
cin.get();
return 0;
}
and here is my System::IO namespace + stream class:
namespace System
{
namespace IO
{
class File
{
public:
static char* ReadAllBytes(const char *name)
{
ifstream fl(name, ifstream::in|ifstream::binary);
fl.seekg( 0, ifstream::end );
size_t len = fl.tellg();
char* ret = new char[len+1];
ret[len] = '\0';
fl.seekg(0);
fl.read(ret, len);
fl.close();
return ret;
}
//not sure of this use yet.
static size_t fileSize(const char* filename)
{
ifstream in(filename, ifstream::in | ifstream::binary);
in.seekg(0, ifstream::end);
return in.tellg();
}
};
class Stream
{
public:
const char *_buffer;
__int64 _origin;
__int64 _position;
__int64 _length;
__int64 _capacity;
bool _expandable;
bool _writable;
bool _exposable;
bool _isOpen;
static const int MemStreamMaxLength = 2147483647;
Stream()
{
InitializeInstanceFields();
}
Stream(const char *buffer)
{
_buffer = buffer;
_length = strlen(_buffer);
_capacity = _length;
_position = 0;
_origin = 0;
_expandable = false;
_writable = true;
_exposable = true;
_isOpen = true;
}
int ReadByte()
{
if (_position >= _length)
return -1;
return _buffer[_position++];
}
void Read(char* &buffer, int offset, int length)
{
if((_position + offset + length) <= _length)
{
memcpy( buffer, _buffer + (_position + offset), length );
_position += length;
}
}
private:
void InitializeInstanceFields()
{
_origin = 0;
_position = 0;
_length = 0;
_capacity = 0;
_expandable = false;
_writable = false;
_exposable = false;
_isOpen = false;
}
};
}
}
This is what ends up happening:
Can anyone explain why this happens, how I can fix, or anything else? I'm new to C++ so any explanations would help. Also please don't criticize my scripting, I know it may be bad, outdated, deprecated, etc. but I'm open to learning and any helping advice goes for the better. :)
You can only use operator << (char *) on C-style strings, not arbitrary arrays of characters. How would you expect it to know how many characters to output?
I would guess the file was not opened correctly and thus the magic buffer is not set at all which leaves it with initialized junk data:
If the constructor is not successful in opening the file, the object
is still created although no file is associated to the stream buffer
and the stream's failbit is set (which can be checked with inherited
member fail).
http://www.cplusplus.com/reference/fstream/ifstream/ifstream/
Try adding more error checking along the way (using cout), especially when opening and reading the buffer. Perhaps set the magic buffer to zero or something recognizable that is overwritten when successful.
I just found an elusive bug in a program and it turned out to be because with optimization enabled, in something like the following sometimes the std::string is destroyed before processDocument() got the text out of it:
#include <stdio.h>
#include <spawn.h>
#include <string>
static void processDocument(const char* text) {
const char* const argv[] = {
"echo",
text,
NULL,
};
pid_t p;
posix_spawnp(&p, "echo", NULL, NULL, (char**) argv, environ);
}
static int mark = 'A';
static void createDocument() {
const char* vc;
std::string v = "ABCKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK42";
++mark;
v[0] = mark;
vc = v.c_str();
processDocument(vc);
}
int main() {
createDocument();
createDocument();
return(0);
}
How do I safely convert a std::string to a char* for use in execvp, posix_spawnp etc ?
I found out why it really was (here the actual minimal testcase):
std::string resultString;
const char* nodeText;
const char* altText;
resultString = "......whatever1.";
nodeText = resultString.c_str();
resultString = ".....whatever2..";
altText = resultString.c_str();
printf("%s\n", nodeText); // garbage
Bad idea.