Does move semantic unsuitable to the array in C++11? - arrays

I test the unique_ptr<> as follow
#include <iostream>
#include <memory>
using namespace std;
class A
{
public:
virtual ~A() {}
virtual void print()
{
cout << "A::Print()" << endl;
}
};
class B : public A
{
public:
virtual ~B() {}
virtual void print()
{
cout << "B::Print()" << endl;
}
};
int main()
{
A a;
B b;
A* arr[2] = {&a, &b};
arr[0]->print();
arr[1]->print();
unique_ptr<A*[]> ptr(move(arr));
/*
unique_ptr<A*[]> ptr(new A*[2]{&a, &b});
*/
ptr[0]->print();
ptr[1]->print();
return 0;
}
It get the result like (g++ 4.7.3)
A::Print()
B::Print()
A::Print()
B::Print()
Aborted (core dumped)
It seem like the ptr and arr point to the samething and when call
destructor, it has been deleted twice.
Why the move semantic don't take effect here?
Does it unsuitable to the array or it is about the unique_ptr?

The problem here is that unique_ptr<T> assumes that the object it manages was allocated with new. Since it is statically allocated on the stack instead, the unique_ptr destructor crashes when it tries to delete your array.
I'm not sure what you're trying to achieve with this unique_ptr anyways. Unique pointers make sure that the managed object is deleted at the end of the scope, but arrays allocated on the stack are deleted at the end of the scope, inherently. Would you have no unique_ptr, your code would function the same and not leak anyways.

The problem here is that you have no dynamically allocated memory here (never use the new keyword). So the unique_ptr is trying to free memory (call delete on) that was never allocated. My suggestion try to write simpler code, because you do a ton of things that are very unconventional.
You store A* for no reason, they will be delete automatically, I can't think of any good reason to store them as pointers
You don't use any standard library containers, you could use a std::array<A,2> instead of a c-style array
Also I'm guessing you just made this as a test so I can't really tell what your trying to achieve here

Related

Returning multiple values from a function

After reading this article I understand the methods for returning multiple values using structs or pointers (the first two). However, after describing the third method (using a temp array), the author writes:
We should not use this approach as the variable information is not
passed to the caller function. For example, we’re using the array’s
index to retrieve the values of our variables. Also, note that we have
to allocate the array dynamically in a heap. If we use the static
array, it ceases to exist when we exit the function, and accessing it
inside the caller function will result in undefined behavior.
This is the code example the author provides:
#include <stdio.h>
#include <stdlib.h>
 
// Function to return multiple values using an array
int* initialize()
{
    // Important: Dynamically allocate memory
    int *temp = (int*) malloc(sizeof(int) * 3);
 
    *temp = 10;
    *(temp + 1) = 20;
    *(temp + 2) = 30;
 
    return temp;
}
 
// Return multiple values from a function in C
int main(void)
{
    int a, b, c;
 
    int *arr = initialize();
 
    a = arr[0];
    b = arr[1];
    c = arr[2];
 
    printf("a = %d, b = %d, c = %d", a, b, c);
 
    // free memory
 
    return 0;
}
I don't understand what the author means, because I tried this method in a small program I wrote and it seems to works just fine, i.e. I can access the returned array's elements in the caller function. Why is this not recommended?
The referenced text is unclear and confusing at best. At worst, outright wrong.
We should not use this approach as the variable information is not passed to the caller function.
It's unclear what "variable information" means here. The actual values is getting back to the caller so that's not the problem. Maybe "variable information" is supposed to mean something like "information about number of variables" but that's unclear.
For example, we’re using the array’s index to retrieve the values of our variables.
Yes, well, of cause... If the values are being sent back in a (dynamic allocated) array, we have to use array indexing to get them. That's obvious and not really a problem.
Also, note that we have to allocate the array dynamically in a heap.
Finally something clear and correct.
If we use the static array, it ceases to exist when we exit the function, and accessing it inside the caller function will result in undefined behavior.
Here it's very unclear what "the static array" refers to. There is no static array in the code. It seems to be refering to some code only available in the authors head...
If the author is thinking about code like:
int temp[3]; // Instead of malloc
then the author is correct. But... that's not a static array so ....
If the author is thinking about code like:
static int temp[3]; // Instead of malloc
then the author is wrong. Due to static this array can be accessed from the caller.
So again... very confusing...
To answer your question:
Why is this not recommended?
Well, some concerns could be:
Dynamic allocation is an expensive operation. So don't use it unless you have a good reason.
Returning dynamic allocated memory from function and relying on the caller to free it later on is a source of many memory leak bugs. So avoid doing that.
BUT...
Good pratice rules nearly always comes with exceptions.
For instance consider a function that returns a rather huge and unknown number of results. For such a function it can be fine to return a pointer to dynamic allocated memory. But you would also need to return the actual number of results. It could look like:
int foo(int ** a)
{
// Generate results and use code like
*a = malloc(.. a lot ..)
...
// Perhaps some realloc(.. even more ..)
...
return number_of_results; // or perhaps -1 on error
}
int * a;
int results = foo(&a);
if (results > 0)
{
....
for (int i=0; i < results; ++i)
{
// Do something with a[i]
...
}
....
free(a);
}
...
If we use the static array, it ceases to exist when we exit the
function, and accessing it inside the caller function will result in
undefined behavior.
It is rubbish. static automatic array will still exist after the function return. It is because such array has static storage duration The function will be not reentrant.
The author probably meant automatic storage duration array.
Undefined behaviour (UB):
int *foo(void)
{
int array[10];
/* ... */
return array;
}
No undefined behaviour:
int *bar(void)
{
static int array[10];
/* ... */
return array;
}

Is it possible to store function arguments in a pointer to function?

Just out of curiosity, I'm trying to understand how pointers to functions work in C.
In order to associate a function to a typedef, I've declared a pointer in it, and then I've stored the address of the desired function in there.
This is what I was able to achieve:
typedef struct
{
void (*get)(char*, int);
char string[10];
} password;
int main()
{
password userPassword;
userPassword.get = &hiddenStringInput;
userPassword.get(userPassword.string, 10);
return EXIT_SUCCESS;
}
While this does actually work perfectly, I'd like for "userPassword.get" to be a shortcut that when used calls the hiddenStringInput function and fills in the requested arguments (in this case, an array of characters and a integer).
Basically, since I'm always going to use userPassword.get in association with the arguments "userPassword.string" and "10", I'm trying to figure out a way to somehow store those parameters in the pointer that points to the hiddenString function. Is it even possible?
The way I see this usually done is by providing a "dispatch" function:
void get(password * pw) {
pw->get(pw->string, 10);
}
Then, after setting userPassword.get to your function, you call just:
get(userPassword);
Obviously this adds some boilerplate code when done for multiple functions. Allows to implement further funny "class like" things, though.
You can do this in Clang using the "Blocks" language extension. As commented, there have been attempts to standardize this (and it's not been received with hostility or anything), but they're moving slowly.
Translated to use Blocks, your example could look like this:
#include <stdlib.h>
#include <Block.h>
typedef void (^GetPw)(int); // notice how Block pointer types are used
typedef void (*GetPw_Impl)(char*, int); // the same way as function pointer types
typedef struct
{
GetPw get;
char string[10];
} password;
extern void hiddenStringInput(char*, int);
extern void setPw(char dst [static 10], char * src);
GetPw bindPw (GetPw_Impl get_impl, char * pw)
{
return Block_copy (^ (int key) {
get_impl (pw, key);
});
}
int main()
{
password userPassword;
setPw(userPassword.string, "secret");
userPassword.get = bindPw(hiddenStringInput, userPassword.string);
userPassword.get(10);
return EXIT_SUCCESS;
}
There are some subtleties to the way arrays are captured that might confuse this case; the example captures the password by normal pointer and assumes userPassword is responsible for ownership of it, separately from the block.
Since a block captures values, it needs to provide and release dynamic storage for the copies of the captured values that will be created when the block itself is copied out of the scope where it was created; this is done with the Block_copy and Block_release functions.
Block types (syntactically function pointers, but using ^ instead of *) are just pointers - there's no way to access the underlying block entity, just like basic C functions.
This is the Clang API - standardization would change this slightly, and will probably reduce the requirement for dynamic memory allocation to copy a block around (but the Clang API reflects how these are currently most commonly used).
So, I've just realized that I can write functions directly inside of structs
typedef struct
{
char string[10];
void get(void)
{
hiddenStringInput(string, 10);
return;
}
void set(const char* newPassword)
{
strcpy(string, newPassword);
return;
}
void show(void)
{
printf("%s", string);
return;
}
} password;
Now I can just call userPassword.get(), userPassword.show() and userPassword.set("something"), and what happens is exactly what the label says. Are there any reasons I shouldn't do this? This looks like it could come pretty handy.
EDIT: So this is only possible in C++. I didn't realize I'm using a C++ compiler and by attempting to do random stuff I came up with this solution. So this isn't really what I was looking for.

Does shared_ptr free memory allocated on the heap?

So in my job I don't have access to the full std library because....just because (corporate nonsense reasons). I can't use unique_ptr but I have access to shared_ptr and I'm working with c++11. So...
I am using a pre-existing (internal) library function that gets data for me and returns it via a raw point (lets say uint8_t*). And I am want to store this data in my class as a shared_ptr.
According to Will a shared_ptr automatically free up memory?
and http://herbsutter.com/2013/05/29/gotw-89-solution-smart-pointers/
it appears that if I allocate memory on the heap and store this in a shared_ptr, the smart pointer should deallocate the memory (of uint8_t* data) for me. Is this true? Any links to literature would help. Also, from these links it seems that I can't use make_shared because I am "adopting a raw pointer from somewhere else."
class myClass
{
public:
shared_ptr<uint8_t> iv_data;
// rest of class
};
other function scope
data_size = getDataSize(...); // legacy internal function
uint8_t* data = new uint8_t[data_size];
getData(data, data_size); // legacy internal function
myClass object;
object.iv_spd_data = std::shared_ptr<uint8_t>(l_spd_data);
// if scope ends here will I get a memory leak for not freeing data
Here is an example of using shared_ptr<> with an array type and custom deleter. I've added some print statements to show the flow through the program. Note you don't need to know the size allocated when deleting, just that the type is an array. Not deleting with delete[] for an allocated array is undefined behavior; that is why the custom deleter is required.
See it in action on ideone
#include <iostream>
#include <memory>
#include <cstdint>
using namespace std;
template< typename T >
struct array_deleter
{
void operator ()( T const * p)
{
cout << "using delete[]" << endl;
delete[] p;
}
};
int8_t* allocate_func()
{
cout << "allocating array" << endl;
return new int8_t[10];
}
int main() {
int8_t *ptr = allocate_func();
cout << "creating smart pointer" << endl;
shared_ptr<int8_t> sptr(ptr, array_deleter<int8_t>());
cout << "exiting main" << endl;
return 0;
}
I suppose that line:
object.iv_spd_data = std::shared_ptr<uint8_t>(l_spd_data);
should be:
object.iv_data = std::shared_ptr<uint8_t>(l_spd_data);?
shared_ptr can share ownership of pointer with other shared_ptr objects. When the last of shared_ptr owning your pointer is destroyed, then your object to which pointer is pointing to is deleted.
With object.iv_data = std::shared_ptr<uint8_t>(l_spd_data); you are creating temporary shared_ptr and assigning it to object.iv_data. Actually you are sharing ownership on l_spd_data between object.iv_data and temporary shared_ptr. Since temporary shared_ptr is destroyed right after this statement, the only owner is now object.iv_data. When myClass object is destroyed, iv_data is destroyed and l_spd_data deleted.
So you will not get memory leak in this case.

Smart Pointers in a language that compiles to C

I'm writing a simple language that compiles to C, and I want to implement smart pointers. I need a bit of help with that though, as I can't seem to think of how I would go around it, or if it's even possible. My current idea is to free the pointer when it goes out of scope, the compiler would handle inserting the frees. This leads to my questions:
How would I tell when a pointer has gone out of scope?
Is this even possible?
The compiler is written in C, and compiles to C. I thought that I could check when the pointer goes out of scope at compile-time, and insert a free into the generated code for the pointer, i.e:
// generated C code.
int main() {
int *x = malloc(sizeof(*x));
*x = 5;
free(x); // inserted by the compiler
}
The scoping rules (in my language) are exactly the same as C.
My current setup is your standard compiler, first it lexes the file contents, then it parses the token stream, semantically analyzes it, and then generates code to C. The parser is a recursive descent parser. I would like to avoid something that happens on execution, i.e. I want it to be a compile-time check that has little to no overhead, and isn't full blown garbage collection.
For functions, each { starts a new scope, and each } closes the corresponding scope. When a } is reached, the variables inside that block go out-of-scope. Members of structs go out of scope when the struct instance goes out of scope. There's a couple exceptions, such as temporary objects go out-of-scope at the next ;, and compilers silently put for loops inside their own block scope.
struct thing {
int member;
};
int foo;
int main() {
thing a;
{
int b = 3;
for(int c=0; c<b; ++c) {
int d = rand(); //the return value of rand goes out of scope after assignment
} //d and c go out of scope here
} //b goes out of scope here
}//a and its members go out of scope here
//globals like foo go out-of-scope after main ends
C++ tries really hard to destroy objects in the opposite order they're constructed, you should probably do that in your language too.
(This is all from my knowledge of C++, so it might be slightly different from C, but I don't think it is)
As for memory, you'll probably want to do a little magic behind the scenes. Whenever the user mallocs memory, you replace it with something that allocates more memory, and "hide" a reference count in the extra space. It's easiest to do that at the beginning of the allocation, and to keep alignment guarantees, you use something akin to this:
typedef union {
long double f;
void* v;
char* c;
unsigned long long l;
} bad_alignment;
void* ref_count_malloc(int bytes)
{
void* p = malloc(bytes + sizeof(bad_alignment)); //does C have sizeof?
int* ref_count = p;
*ref_count = 1; //now is 1 pointer pointing at this block
return p + sizeof(bad_alignment);
}
When they copy a pointer, you silently add something akin to this before the copy
void copy_pointer(void* from, void* to) {
if (from != NULL)
ref_count_free(free); //no longer points at previous block
bad_alignment* ref_count = to-sizeof(bad_alignment);
++*ref_count; //one additional pointing at this block
}
And when they free or a pointer goes out of scope, you add/replace the call with something like this:
void ref_count_free(void* ptr) {
if(ptr) {
bad_alignment* ref_count = ptr-sizeof(bad_alignment);
if (--*ref_count == 0) //if no more pointing at this block
free(ptr);
}
}
If you have threads, you'll have to add locks to all that. My C is rusty and the code is untested, so do a lot of research on these concepts.
The problem is slightly more difficult, since your code is straightforward, but... what if another pointer is made to point to the same place as x?
// generated C code.
int main() {
int *x = malloc(sizeof(*x));
int *y = x;
*x = 5;
free(x); // inserted by the compiler, now wrong
}
You doubtlessly will have a heap structure, in which each block has a header that tells a) whether the block is in use, and b) the size of the block. This can be achieved with a small structure, or by using the highest bit for a) in the integer value for b) [is this a 64bit compiler or 32bit?]. For simplicity, lets consider:
typedef struct {
bool allocated: 1;
size_t size;
} BlockHeader;
You would have to add another field to that small structure, which would be a reference count. Each time a pointer points to that block in the heap, you increment the reference count. When a pointer stops pointing to a block, then its reference count is decremented. If it reaches 0, then it can be compacted or whatever. The use of the allocated field has now gone.
typedef struct {
size_t size;
size_t referenceCount;
} BlockHeader;
Reference counting is quite simple to implement, but comes with a down side: it means there is overhead each time the value of a pointer changes. Still, is the simplest scheme to work, and that's why some programming languages still use it, such as Python.

C Structures: Initialized Strings become invalid

I have the following code example which gets a pointer to a structure in two different ways. While the first one ("Test1") succeeds, the second one fails with a Segmentation fault when trying to output the string (title), while the number (type) is printed properly:
#include <stdio.h>
#include <stdlib.h>
typedef struct{
unsigned char type;
char* title;
} MenuItem;
typedef struct{
unsigned short itemCount;
MenuItem *items;
} Menu;
Menu* createMenu(unsigned short itemCount, MenuItem items[]){
Menu *menu = malloc(sizeof(Menu));
menu->itemCount = itemCount;
menu->items = items;
return menu;
}
Menu* getSampleMenu(void){
return createMenu(2,(MenuItem[]){
{3,"Foo2"},
{4,"Bar2"}
});
}
void showMenu(const Menu *menu){
for(unsigned short i = 0; i < menu->itemCount; i++)
printf("Item %d: %d/%s\n",i,menu->items[i].type,menu->items[i].title);
}
int main(void){
//Test 1
Menu *menu = createMenu(2,(MenuItem[]){
{1,"Foo"},
{2,"Bar"}
});
showMenu(menu);
//Result: 1/Foo\n 2/Bar
//Test 2
showMenu(getSampleMenu());
//Result: 3/ [segmentation fault]
}
Do you have any idea what the problem might be? The example is compiled and tested on Debian using gcc 4.6.3 in C99 mode.
Thanks in advance!
The array you're passing to createMenu has "automatic storage duration". It dies, and any pointers to it become invalid, once getSampleMenu ends.
(Edit: It might actually be even more severe than that. The array, being a temporary object, may well be dead once the statement that caused its creation ends. In this case the two are about equivalent, since that statement is the last one in the function...but were there subsequent statements in createSampleMenu that attempted to use that menu, even they may be following invalid pointers.)
You'll need to dynamically allocate (malloc) some memory and copy the array into it. (Of course, then you should also have a destroyMenu or similar function to properly free the memory once the menu's no longer needed.)
Variables that are declared locally, also called "automatic", are usually stored on the stack frame of the current function - so that when you return from the function in which they were declared, they are popped from the stack, and a function called later could write over them. malloc allocates a range of memory on the heap, which remains allocated to your use until you call free, regardless of the scope your code is in.
The pointer menu->items is lo longer valid once the function getSampleMenu() returns because "MenuItem[]" is locally defined in this function.
So in test 2, your program segfault when accessing menu->items in showMenu().

Resources