I read more than once that passing by reference is simply passing a pointer, which is automatically dereferenced within a function. How true is this?

For example, I wrote the following dll (in Visual Studio):

extern "C" void __declspec(dllexport) test(int* i) { cout << "test(" << *i << ")\n"; (*i)++; } 

And such a program to work with it:

 typedef void (*myfunc)(int&); int main() { HMODULE dll; if ((dll = LoadLibrary("Dll.dll")) != NULL) { myfunc f = (myfunc)GetProcAddress(dll,"test"); int q = 5; cout << "q = " << q << endl; f(q); cout << "q = " << q << endl; FreeLibrary(dll); } } 

Everything works, it turns out that I wanted:

 q = 5 test(5) q = 6 

Just how much can you rely on this transfer by reference as a pointer? What could be the trouble?

And I also immediately wanted to ask, for example, I use cout in a dll - is it the same cout as in the main program or not? And if I pass a pointer to it, then all the same, the code in the dll will be used, and not in the program? Or if I allocate memory in dll, then how to properly free it in the program? For example, if I return the unique_ptr in a function in the dll?

  • Differences may occur when transferring classes. - nick_n_a
  • This is almost always true in terms of internal implementation. This, however, does not mean at all that you have the right to declare a function with a reference parameter, but to define it with a pointer parameter. - AnT

3 answers 3

No, not identical.

A pointer is a physical object in memory that takes up space and is able to meaning.

A link is simply a synonym for the name of an object for which no additional memory is allocated.

In other words, when you operate with links, you can imagine that you work with the same variable as in the declaration (for the compiler, there is no difference in this case).


In the case of using dynamically connected libraries, a strict recommendation is to use the C interface (in C there are only pointers) in order to be able to work with a library from other languages. It is not necessary to return std :: unique_ptr <> in this case.

Also about the allocation of memory, if you allocate memory inside the library, then inside and must release.

The use of smart pointers in this case is a modern memory tracking approach. Try to avoid explicit calls to delete .

First of all, you need to decide whether you really need to allocate memory within the library or whether it is permissible to transfer the buffer and its size to it.


If the library still needs to allocate memory and return it, then let's say we have two functions:

void* dll_alloc(size_t size) and dll_free(void* ptr)

Then for convenient work and automatic release of memory, we can use the following:

std::shared_ptr<void> dllMemory(dll_alloc(1024), dll_free);

In this case, we do not need to explicitly call dll_free .

    You have no right to assume that the link inside is arranged as a pointer. A function declaration that differs from its current definition is undefined behavior.

    The fact that this "works" is an accident, as with any UB. With the increasing complexity of the program and / or changing the settings of the compiler, any unpleasant surprises are possible.


    What is true in the words you cited is that the link behaves much like an automatically dereferable pointer.

    An important semantic difference between a pointer and a link is that the link cannot be reassigned, and it necessarily points to some object (in the correct program). That is, there are no "null links".

    • So, as I understand it, you just need not risk it? ) - Mikhailo
    • @Mikhailo: Well, yes, moreover, it is clearly prohibited by the standard. - VladD

    In the first part, I think that there are no instructions in the standard and there should not be any. Frankly, I don’t think that if such a transfer in VC ++ is successful, it will cease to be such at some point ... but I fully admit that the other compiler may work differently. Therefore, it seems to me, within one compiler - roughly speaking, in your program - you can basically use it ... giving the report that theoretically it could break in some future versions.

    But isn't it easier to use an extra level of indirection? Just write an intermediary function that accepts the link but calls the DLL function and passes the address of this link to it?

    In the second part - if you used static libraries, then yes, you have different cout , if dynamic runtime, then I think the same from dynamic libraries.

    As far as memory is concerned, as far as I remember from experienced advice :), it is highly desirable to free memory where it was allocated. But how to reconcile the same intelligent pointers or something else - a simple and reliable way to mind does not yet come.

    • Memory can be freed anywhere, the main thing is that in the heap in which it was allocated. That is, delete should lead to the same runtime as new (which is not obvious in the case of a DLL). The smart pointer should help with the idea, it encapsulates the delete (but I'm not 100% sure). - VladD
    • Although transferring a smart pointer across a DLL boundary is probably not the best idea. - VladD
    • @VladD I was interested in this question, I twirled a little, but ... In general, if you say something clever in response to my question - I would be grateful :) - Harry
    • And how much - being compiled by one compiler, but with static linking runtime - runtime in DLL and EXE can be considered as the same? Do they have their own internal variables, as I understand it, different? - Harry
    • Wrote in response to your question. - VladD