Passing char* by value - c++

Will the following code work? -
void doSomething(char* in)
{
strcpy(in,"mytext");
}
Here's how the function is being called:
doSomething(testIn);
OtherFn(testIn);
The char* in is used in other places in the code... and we are passing it by value to the function doSomething. I understand when we pass by value, a copy of the string stored in char* is copied within the function. So, when we do a strcpy, will it copy to the local copy or to the char* in that was passed in as an argument?
My understanding is we need to do: doSomething(char* &in). Is that right?

When you want to modify just the contents of what the pointer points to, use:
doSomething(char* in)
So, yes,
void doSomething(char* in)
{
strcpy(in,"mytext");
}
will work just fine as long as in points to enough memory to hold "mytest" and a terminating null character.
There are times when you want to modify where the pointer points to, for example, by allocating new memory. Then, you need to pass a reference to a pointer.
void doSomething(char*& in)
{
in = new char[200];
strcpy(in,"mytext");
}
and use it as:
char* s = NULL;
doSomething(s);
// Now s points to memory that was allocated in doSomething.
// Use s
// make sure to deallocate the memory.
delete [] s;

Related

C++ , how come I do not get the value "123456"

I am trying to print out value 123456, but it gives me the garbage value. How can I fix it? And Can you please explain why it gives the wrong value?
#include <stdio.h>
#include <stdlib.h>
struct MyInfo
{
private:
int private_key = 123456;
public:
int setkey(int value)
{
private_key = value;
}
int GetScore()
{
return private_key;
}
};
void main()
{
MyInfo* pMyInfo;
pMyInfo = (MyInfo*)malloc(sizeof(MyInfo));
printf("%d\n", pMyInfo->GetScore());
free(pMyInfo);
}
Don't use malloc/free but rather pMyInfo = new MyInfo() and delete pMyInfo. Only new will call the constructor which initializes the value; only delete will call the destructor.
Regarding the comment, what is meant is, you can also have it on the stack, i.e. MyInfo pMyInfo;, i.e. not a pointer. That will automatically call the constructor and when it goes out of scope, the destructor.
int private_key = 123456;
This really is just a camouflaged constructor initialization which means it's the same as:
MyInfo() : private_key(123456) {}
Since malloc and friends are inherited from C and C has no classes (and thus no special member functions) whatsoever malloc and friends won't call these necessary special member functions to set up your object. The C++ equivalent new does however which is why you should always use new over malloc and delete over free.
But wait, there's more...
Actually, you shouldn't ever use new either, there are always better alternatives than using raw dynamic allocation. If you really need dynamic memory allocation then use std::unique_ptr or for multiple objects std::vector but most of the time you don't even need these ( there are tons of posts on here that explain when dynamic allocation is a must, for all the other cases just use storage with automatic lifetime) all you need in this case is a local object:
MyInfo myInfo;
printf("%d\n", myInfo.GetScore());
See how your code just got shorter, easier to maintain and cleaner to achieve the same?
When you declare a pointer of type MyInfo, it does not mean that the object it points to will actually be your struct, it just assumes it will be.
When you do malloc(sizeof(MyInfo)), you simply allocate memory of the size which your struct might take, it does not create an object. Hence, when you try to do GetScore(), it accesses memory location which it assumes contains your private_key, but instead it simply contains garbage.
Don't mix C and C++
You should avoid malloc/alloc etc in C++ and opt for new operator if you want to work with dynamically allocated objects.
Add a constructor to initialize the value
private;
int private_key;
public:
MyInfo () {
private_key = 123456;
}
And implement the main like
// without pointer
void main () {
MyInfo myinfo;
printf("%d\n", myinfo.GetScore());
}
// with pointer
void main () {
MyInfo *myinfo = new MyInfo();
printf("%d\n", myinfo->GetScore());
}
Just for reference, it is possible to initialize an object in raw storage, but it would be overkill and rather stupid for this use case. As malloc only allocate raw memory and does not construct an object, you could use a placement new to build the object in a second time:
int main() // I can't stand void main
{
MyInfo* pMyInfo;
pMyInfo = (MyInfo*)malloc(sizeof(MyInfo)); // only allocate raw memory
new((void *) pMyInfo) MyInfo; // construct the object
std::cout << pMyInfo->GetScore() << std::endl; // no reason for C printf here
pMyInfo->~MyInfo(); // placement new requires explicit destructor call if not trivial
free(pMyInfo);
return 0;
}
DO NOT DO THAT for such a simple case. Placement new should only be used in very special cases where the allocation is not trivial, for example when you use share memory. But here the correct way is to simply use an automatic object:
int main() // I can't stand void main
{
MyInfo pMyInfo;
std::cout << pMyInfo.GetScore() << std::endl;
return 0;
}

figuring out value semantics in C++

I have a class String with the following members:
Class String{
...
private:
char* word
int length
}
String's copy assignment returns a String& and allocates word on the heap.
I also have a linked list class written in C that has a function:
void *popFront(struct List *list)
{
struct Node prevHead = list->head
list->head = prevHead->next;
void *info = prevHead->info;
free(prevHead);
return info;
}
My task is to write the same function for a C++ linked list that uses the C function. This is what I have:
String List::popFront()
{
String s = (*(String *) ::popFront(&list));//casting the void * to String
return s;
}
The C++ method should return the object by value. That's what I thought the method would do. However,
I'm getting memory leaks. Any hint on how I need to modify List::popFront() so that it returns by value? Thanks.
First store the returned pointer locally as a pointer to string, then make a local copy of the string, then delete the object, the pointer points to and finally return the local copy.
EDIT:
Btw. you can use c++11's smart pointers to avoid the extra copy:
String List::popFront()
{
auto s = std::unique_ptr<String>((String*) ::popFront(&list));
return *s;
}
but that is probably not, what your teacher aims at.
popFront removes the element from the linked list and frees the node, but not the info portion. This is the responsibility of the caller of popFront, e.g.
String *s = (String *) ::popFront(&list);
delete s;
But you must also keep a copy, which you can return from the method
String List::popFront()
{
String *s = (String *) ::popFront(&list);
String tmp = *s;
delete s;
return tmp;
}
You declare String List::popFront() which returns an object, not a pointer. And String s = ... declares an object, not a pointer or reference. So assigning s a value constructs a new object s being a copy of what ::popFront returned, then a next copy of s is returned and s itself gets destroyed. However the object unlinked by ::popFront() remains on a heap, making a leak.
Don't create an intermediate copy of String object, return the pointer to unlinked object, so that a caller can link it to its own list or delete it after use:
String *List::popFront()
{
String *s = (String *) ::popFront(&list);//casting the void * to String *
return s;
}

Who should free Memory? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
delete heap after returning pointer
I have a class with a member function:
char* toChar();
The member function allocates memory and return a pointer to that memory ...
lets say I would use it like this:
int main() {
MyClass mc = new MyClass();
char* str = mc.toChar();
return 0;
}
where should I free the memory? In the Destructor of the class or in the program like this:
int main() {
MyClass * mc = new MyClass();
char* str = mc.toChar();
// tostuff with str
delete mc;
delete[] str;
return 0;
}
If you want it to be reusable (that is, you can call it multiple times and it may return different values, maybe because the class has changed), then you should free it in the main. Otherwise it's up to you.
But in general you should NOT use plain strings. You should change it to use std::string and then return that by value.
The member function should return an object that manages the memory. Typically that would be std::unique_ptr, but for char data std::string may be more appropriate:
class MyClass {
...
std::string toChar();
};
int main() {
MyClass mc;
std::string str = mc.toChar();
}
Note that by also making mc a managed object (here it is managed directly on the stack; unique_ptr would also work but would be largely unnecessary) there is no need for delete to appear anywhere in your code. In general, unless you are writing your own containers, delete should not appear in your code.
The question is who is the "owner" of that piece of memory pointed by str. As mc returns a char* instead of a const char*, it allows the client (str) to modify the value of the string, so I would say str should also consequently take care of freeing the memory. What would happen if mc frees the memory but str still want to access it? The process will be terminated.

Reading new, filled array gives segfault

I've been banging my head hard over this...I create a pointer in main(), which I pass on to another function. Inside that function, the pointer is used to create a new array (using the new operator), the array is filled, and the function ends.
If I then try to access elements in the new array in the caller, I get a segfault. Since the new operator was used, I expect the new array to be on the heap and thus not cleared by it going out of scope...I really don't get this. What am I overlooking? I also don't know precisely what to google for, so no luck there yet.
I can get it to work if I let the function return the pointer (instead of passing it), but I don't want to do that because eventually I'd like my function to create a few such newly created arrays. So what am I missing here?
Here is a minimal working example:
#include <iostream>
#include <stdio.h>
bool getData(double *myData)
{
myData = new double[2];
if (!myData)
return false;
myData[0] = +4.53;
myData[1] = -3.25;
return true;
}
int main()
{
double *myData = NULL;
if (!getData(myData))
fprintf(stderr, "Could not get data.\n");
std::cout << myData[0] << std::endl;
std::cout << myData[1] << std::endl;
delete [] myData;
}
Root Cause of the Crash:
When you pass a pointer to the function by value. An copy of the pointer gets passed to the function. Further You allocate memory to the copy of pointer passed through main, this pointer is not same as the one you access in main, it is an copy. The pointer myData in main was never allocated any memory, so eventually you are dereferencing a NULL pointer which results in a Undefined Behavior and an crash.
Suggested Solution 1:
Pass the pointer by Reference:
bool getData(double *&myData)
^
And you are good to go.This is the C++ way of doing it.
Another Solution:
You could also do:
bool getData(double **myData)
^
{
*myData = new double[2];
//so on
}
while calling it as:
getData(&myData);
^
A word of caution:
new does not return NULL in case of failure to allocate memory. It throws a std::bad_alloc exception. So you need to handle that exception or in case you want to check for null you should use the nothrow version of new.
The pointer argument to getData() is passed by value, not by reference. This means you're pushing the value (== the address the pointer points to) on the stack and call getData. Inside getData you overwrite this value with the return value from new[]. This value is no longer valid after returning from the function as it only existed on the stack.
Try to pass a reference or pointer to the pointer:
bool getData(double *&myData)
{
myData = new double[2];
if (!myData)
return false;
myData[0] = +4.53;
myData[1] = -3.25;
return true;
}
You have to pass a double** as myData, to initialize correctly your array. Currently, your getData function creates an array and stores its value in the copied parameter, so myData in main is not modified. Your must pass the pointer of myData and modify it with
bool getData(double** myData)
{
*pmyData = new double[2];
...
}
and call getData in main:
getData(&myData);
The myData given as parameter to getData function is passed on stack as a copy. When modifying that value in getData function you actually modify the value from the stack.
When you return to the main function everything is as it was before (except a memory leak).
The quickest solution would be to change the getData function like this:
bool getData(double *&myData)
and you're all set.
You pass the pointer into your function by value, not reference. Try this:
bool getData(double* &myData)
{
...
}
The difference is that myData is now a reference to the pointer in main, not a copy of it that gets destroyed when the function exits.

Destructor on const char *

In my program, i have line like this:
const char * str = getStr();
Do i need to call destructor on str [] at the end of function to prevent memory leaks?
Question does not contain enough information to tell, it depends what getStr() does. For example:
const char *getStr() {
return "boo";
}
then you must not call delete.
const char *getStr() {
return new char;
}
then you should call delete str; to avoid a memory leak (and must not call delete[]).
const char *getStr() {
return new char[10];
}
then you should call delete[] str; to avoid a memory leak (and must not call delete).
const char *getStr() {
return 0;
}
then it doesn't matter what you do, calling any kind of delete on str has no effect.
Ownership of resources, and how to release any resources owned, are part of the interface to a function, and should be documented at the same time as you document what the return value actually is.
It all depends on what getStr() does. It may even be that you have to call free on the pointer if getStr() created it with malloc. It may be that getStr() is returning a pointer to a static area (not very thread safe, but it happens) or any number of other things.
Part of the contract and documentation for getStr() should be who owns the pointer it returns.
Here are some examples of possible getStr() functions...
In this case getStr() owns the pointer and you don't have to do anything to free it. OTOH, what's being pointed at may change the next time you call getStr() so you should probably make your own copy if you need to keep it around for any length of time:
const char *getStr()
{
static char buf[30] = "Silly counter";
buf[0] = buf[0] + 1;
return buf;
}
In this case, you will eventually need to call free on the pointer returned:
const char *getStr()
{
return strdup("Silly string");
}
In this case, you will need to call plain old delete on the pointer returned:
const char *getStr()
{
return new char;
}
In this case, you will need to call delete [] on the pointer returned:
const char *getStr()
{
return new char[50];
}
There are many other possibilities. As I stated previously, part of the contract for a function (which should appear in its documentation) is who owns the pointer returned and how that data pointed to must be disposed of if doing so is the caller's responsibility.
It depends on how getStr() has been designed. It could return a pointer to a string that is still owned by someone else (and in this case the answer is no) or it may return a pointer to and the caller becomes the owner (and in this case the answer is yes).
You should check the documentation of getStr to know.
If the ownership of the returned area is of the caller then probably in C++ returning an std::string would have been a much better idea.
It's a good idea to do so if it's going out of scope. I'd recommend also setting the pointer to null to ensure it isn't dangling:
delete[] str;
str = null;