After allocating and initializing a char* and copying a data for it
char * uri= new char [strlen(realm) + strlen("sip:") +1]();
strcpy(uri, "sip:");
strcat(uri, realm);
I pass this char* to pj_str(char*) function. This function convert the char* to pj_str_t struct that contains a pointer to the buffer and its length.
Then the function continue its logic and uses the uri pj_str.
Before the function return, it's supposed to deallocate *uri. When doing this line of code the first two characters contain an octal garbage data else it contains the expected data.
delete [] uri;
What is the problem?!
Isn't it enough to do
delete [] uri;
Related
Is it possible to add a string to a string pointer in C++?
Not working example:
String* temp;
temp[0] = "string";
Just like it's possible in:
String temp[3];
temp[0] = "string";
Before suggesting to just use a normal array or copy it to a different fixed array, the string pointer needs to be returned in a function. Eg.
String* SomeClass::toArray(String str)
I am also open to other suggestions how I can return an array from this function.
Independing of what is String this code snippet
String* temp;
temp[0] = "string";
if it is compiled results in undefined behaviour because the pointer temp either has an indeterminate value (if it is a local variable) or NULL and you may not derefence it.
Provided that this code snippet
String temp[3];
temp[0] = "string";
is valid you could write for example
String* other_temp = temp;
other_temp[0] = "string";
you can't add anything to POINTER, pointer is just pointing to some memory.
You need first to have some instance, like in your second example String temp[3]; you are creating three instances of String.
So String temp; will create local instance of String, then to get it's pointer you can use String * tempPtr = &temp;, but I don't see why you would want that, as you can use temp as is... like temp.clear(); or whatever functions the class String has (see it's API).
Edit about returning String pointer.
That's sort of unfortunate C++ API design. So who will own the memory of that instance?
For example:
String* SomeClass::toArray(String str) {
String result;
// BUG, DO NOT DO THIS!
return &result; // returns pointer to local stack variable
// which gets released *here*, invalidating the pointer
}
String* SomeClass::toArray(String str) {
String *result = new String;
return result; // returns pointer to global heap
// now if the upper layer of code will not call "delete" on it
// you have memory leak
}
BTW, from the "toArray" name it looks like you want array of String instances, not String pointer. So that functions should be rather defined as String[] SomeClass::toArray(String str), still having the same problem with memory ownership.
What I would do is not return an array.
maybe void SomeClass::toArray(const String & str, std::vector<String> & array), filling up the data into array vector.
I do not know how much you use C++ on arduino, if std::vector is OK, or not, but having a class for String feels like vector<> will be OK too, especially if you are wasting your stack by passing copy instance of String instead of reference. (unless String is some macro/typedef for char[], please, don't tell me that... I mean, even C++ can be written in low memory footprint way, you don't have to hardwire arrays everywhere, if you avoid unnecessary allocation of temporary instances of C++ classes).
I want to pass string to second function where it fills the character array and gives the value back. In the first function I want to take the string length after second function fills it.
first step
Planning to pass the character array
char data[10]="";
GetData(data); // Here Iam doing memset value to data
strlen(data);
second step
Planning to pass the character pointer
char *data;
GetData(data); // what I should do
strlen(data);
Can someone suggest which is the best practice
You want to use std::string, something like:
std::string data;
void GetData(std::string& str);
passing by non-const reference allows GetData to alter str.
Ideally the character pointer should be owned by the caller, and should take care of allocation (if possible, or callee has to do that on behalf of the caller) and deallocation
char *data = (char *) NULL; // should initialize to know allocated or not
the prototype of the call, GetData should be:
void GetData(char *& d); // pointer passed as reference
Within GetData, d shoud be allocated as:
d = new char[size]; //size should be appropriately decided including null terminating character
for example, if you wish to store a "hello" say, d should be allocated as :
d = new char[5+1]; // example
once done, in the caller, you must deallocate as:
if (data) delete [] data;
data = (char *) NULL;
The "classic", C-compatible method in Windows (where Visual C++ is most used) is to have a function that takes the buffer size as argument, and returns the size or length of data copied. Example:
//Inputs:
// buffer: [out/opt] If not null, write data here.
// size: [in] Buffer size including null terminator, ignored if buffer is null.
//Outputs:
// buffer: The data.
// Return Value: Length of data written to the buffer, without null terminator.
int GetData(char *buffer, size_t bufferSize);
This allows calling the function with a null buffer to obtain the length to allocate, allocate the data, and call the function again.
However, it's not very C++ and it's error-prone. Passing a pointer/reference to the pointer to allocate is better from a language standpoint, but has its drawbacks when crossing a DLL boundary, where it's recommended that any data allocated by a DLL be deallocated by the same DLL (preventing the use of ordinary smart pointers).
This question already has answers here:
Function does not change passed pointer C++
(4 answers)
Closed 8 years ago.
I'm creating a C++ program that uses RapidXML to read data from xml files. Because RapidXML allocates pointers to the xml content to be used to access it, it needs the content of the file to live on as long as it is parsed in further steps.
So I had several files parsed successfully, but at the beginning of every parsing of a file, I always had all of the ifstream and allocating going on. I came up with the idea to create a function that would take in the file path, pointers to the xml_document<> instance and so on and return the root node of the xml file. What I then realised was, that I might hit scope problems with the dynamically allocated char array containing the xml content to be parsed and later pointed to.
I then tried the following technique, where I allocated a char*, xml_document and xml_node and invoked the function to retrieve the root node.
The function:
bool readXML(const char * path, char * buffer, xml_document<> * doc, const char * rootNodeName, xml_node<> * root_node){
// Open file
ifstream file(path, ios::in|ios::binary);
if (!file.is_open()){ err(ERR_FILE_NOTFOUND,path); return 0; }
// Get length
file.seekg(0,file.end);
int length = file.tellg();
file.seekg(0,file.beg);
// Allocate buffer
buffer = new char [length+1];
file.read(buffer,length);
buffer[length] = '\0';
file.close();
// Parse
doc->parse<0>(buffer);
// Get root node
root_node = doc->first_node(rootNodeName);
if ( !root_node ){ err(ERR_FILE_INVALID,path); return 0; }
return 1;
}
The code where I use the function (reading "Hersteller.xml" / initializing class):
bool loadHersteller(){ // v4
// Declare
char * bfr;
xml_document<> doc;
xml_node<> * rt_node;
// Get root node
if (!readXML(concatURL(PFAD_DATEN,"Hersteller.xml"), bfr, &doc, "Hersteller", rt_node)) return 0;
// Extract
if (!initHRST(rt_node)) return 0; // Works fine on it's own (initializes a class)
toConsoleHrst(); // Works fine on it's own (prints data back to console)
// Clean up
delete[] bfr;
doc.clear();
return 1;
} // END loadHersteller()
Now what I get from that is a blank console and a crash with it, returning an interger.
I am very certain that the problem is the scope or lifetime of the char array. The goal of this function is to do all the work of retrieving xml files / allocating the buffer for me and passing me the root node (which I'll right pass to another function). As said, the char array needs to stay alive in the scope where the function was invoked from, so it can be accessed via the pointer structure built by the parser.
To fix this, pass both your out parameters (buffer and root_node) as char*& (reference to char pointer) rather than simply char*. Otherwise, what readXML() receives is a copy of the two pointers, and whatever values you assign to those copies are lost when the function returns and they are destroyed.
Note: There is a potential memory leak in the code because the delete[] instruction won't be reached if either readXml() or initHRST() fails and the function returns early.
Instead of char *, declare function parameters as char **. Inside the function, prefix the parameter name with *. For example, *buffer = new char[length + 1].
When passing a variable to the function, prefix it with &:
if (!readXML(...), &bfr, ...
I've been trying to convert a const char to a char for the past 30 minutes.
Here's what I've got.
string atr;
getline(cin,atr); // Start off with a string because getline takes nothing else.
const char *buffA = atr.c_str(); // Create a const char of the string converted to a const char.
char *buff = ""; // Create a new char to hold the converted result.
strcat(buff,buffA); // Do the conversion.
parseargs(buff); // Pass the data on.
However, I get an unhandled exception. I have no idea why. I literally just typed 'try' into the console as my only argument.
Try using C++ instead of C idioms:
std::vector<char> data(atr.begin(), atr.end());
data.push_back('\0');
parseargs(&data[0]);
There are two things wrong with your code. First, you
initialize a char* with a string literal. This uses
a deprecated convertion; the type of a string literal is char
const[] (which converts to char const*, not to char*),
because any attempt to modify the literal is undefined behavior.
The second is that your string literal is only one char long,
so even if you could write to it, unless atr was empty, you're
writing beyond the end of the buffer.
You don't tell us anything about parseargs. If it doesn't
modify it's argument, you can just pass it atr.c_str(), and be
done with it. (If it's a legacy function which ignores const,
you may have to use a const_cast here.) If it does modify its
argument (say because it uses strtok), then you'll have to
explicitly push a '\0' onto the end of atr, and then pass it
&atr[0]. (Not a particularly clean solution, but if you're
not using atr afterwards, it should work.)
Both your contents of buff and buffA are in read-only memory of the process.
You will actually need to new your buff like
char* buff = new char[32];
This provides memory from the free-store and you can then strcat the string from buffA to buff.
You should prefer strncat, though to avoid buffer-overruns and delete your buff eventually.
This
char *buff = ""; // Create a new char to hold the converted result.
creates a char * that points to (probably read-only) memory of about 1 byte in extent. This:
strcat(buff,buffA); // Do the conversion.
attempts to overwrite that (probably read-only) memory of 1 or so bytes with an arbitrary string.
The chances are this will promptly crash. If the memory is read only, it will crash immediately. If the memory is not read only it will stomp over random data, resulting in very undefined behaviour.
Why on earth do you want to do that? Does parseArgs actually need a modifiable string? It's parsing arguments, it shouldn't need to change them. If it's really necessary, use a std::vector<char> and pass the address of the first element and hope that all it does is poke the contents of the array, rather than (say) running over the end.
One function tries to pass char array to another, but without success:
char * ret() {
char buf[32];
buf[0]='1'; // buf char array contains 1
buf[31]='\0';
printf(buf);
return buf;
}
int multiline() {
char temp[32];
strcpy(temp,ret()); // temp array doesn't contain 1 after this line
temp[31]='\0';
printf(temp);
}
Please tell me, how to fix this issue?
you are returning a pointer to a local variable char buf[32];. This array is allocated on the stack and only valid within the function but not outside of the function.
You get undefined behavior when you access this array.
To return an array like this you should allocate it on the heap, eg. with malloc()
You can fix the issue by not returning a local variable (allocate a string or return a pointer to a statically allocated one):
char * ret() {
char * buf = malloc(32*sizeof(char));
buf[0]='1'; // buf char array contains 1
buf[31]='\0';
printf(buf);
return buf;
}
int multiline() {
char temp[32];
char * returnedString = ret();
strcpy(temp,returnedString);
free(returnedString);
temp[31]='\0';
printf(temp);
}
You can't return a pointer to a local variable; as soon as the function returns, the local variable, along with the rest of the function's stack frame, is destroyed.
Instead, you can return a copy of the array; you could make one using strdup().
As an aside, you're setting the first character of your array, and putting a \0 at the end, but the 30 characters in between just hold garbage. Normally the \0 at the end of a string is immediately after the valid characters, not all the way at the end of the array.