Click here to Skip to main content
15,884,838 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
I want to know on C language or C++, if I can know within a function if the real parameter of a formal pointer input/output parameter, let's say to a byte array or char array, has been passed using an array of defined size (static pointer) or a pointer created with calloc (dynamic pointer) from the caller. The formal parameter could have been defined as an array or as a pointer.

I need to know that because in the second case I could reallocate the memory to return, on this same parameter, a bigger size string compared to the original allocated space.

I have to do this because I am converting an existing library on C# to C, and at first it has to be exactly as the original, so dont scold at me.

I apologize because I dont know the right names for what I called the types of real parameters and someone can be confused but I don know.

Example >
C++
void FunctionName( char sCadenaHexa[], int SizeOfCadena )
{
  ... How I know how was called .... 
}

Called using "array defined size" or "static pointer" :
C++
char sRealCadena[100] = "something";
FunctionName(  sRealCadena, 100 );

Called using a pointer or "dynamic pointer" :
C++
char *sRealCadena = malloc( 100, sizeof(char) );
FunctionName( sRealCadena, 100 );

Of course I will try to redesign the function adding another parameter as the output string paremeter, but as first approach I have to stick to the current design.

If the thread is repeated Im sorry, but I didnt find it.

Thanx in advance
Posted
Comments
Sergey Alexandrovich Kryukov 4-Mar-13 18:07pm    
I voted 4 just for interesting thinking, but no — wrong way. Please see my answer...
—SA

This is a pretty interesting question, but this is not how C or C++ pointers work. There is no a reliable way of knowing if the pointer points to the heap of static region of memory (such as "data segment" in some platforms). In principle, it is possible is some (usually primitive) platforms, but there is no a universal way, and such way cannot exist.

If you think about it, you will see that this is actually good, a right decision. These languages are abstracted from the "types of memory". It allows for implementation of the languages and the applications compiled using those languages to be custom. It also allows to apply the same algorithms to different kinds of pointers. A user can use different types of allocation and deallocation, especially in C++, where the user can define custom new and delete operators. If is very usual to use sub-allocators and other custom memory management facilities.

Instead of finding the method of telling the difference between pointers, you should better design your code properly. If some method returns pointer as a result of allocation, it should be complement by the method used to deallocate memory. The side doing allocation should always deallocate. You should not allow the situations such as when you create a library with some methods are allocating, and the code using the library deallocates. This is a usual design mistakes which totally kills platform compatibility and presents other threats. Avoid it.

—SA
 
Share this answer
 
v7
Comments
Andreas Gieriet 4-Mar-13 18:50pm    
My 5!
I fully agree. Breaking the symetry of reaource aquisition and their release kills the project. I wonder how one manages to re-write a C# library (from a garbage collected environment) into a C++ library (assumebly in a non-garbage collected environment) by mandating to keep the interface unchanged.
I've also seen special memory managements in embedded systems that added some housekeeping in some spare bytes below the returned memory address of the new operator (e.g. some counter and flags, together with some magic pattern/check sum). That was especially useful to detect missing delete[] calls and memory overrides. If I recall correctly, the stack memory was not under control, so that additional housekeeping was not there, and hence, the data that we would have extracted there would have triggered a fault since the magic/checksum was most likely wrong for stack arrays.
Cheers
Andi
Sergey Alexandrovich Kryukov 4-Mar-13 19:01pm    
Thank you, Andi.

Your story about replication of .NET garbage-collected API to C++ is amazing, as well as your absolutely correct reasoning.

Embedded systems... (Sight...) I also remember amazing fault of the developers of hardware vendor software (which way to often is very illiterate) written for native Windows API which, just the opposite, if totally unsuitable for .NET by similar reasons. In that case the situation allowed me to work around it using pinning, which does not mean real sanity. Total pathology.

And, in contrast, nice symmetric approach allows for amazing level of compatibility between very, very different platforms.

Thank you for interesting discussion,
—SA
Never thought about it before - it's a nasty thing to do but I can see your problem.

Does this help? [^]
 
Share this answer
 
Even not rtti would help you, as you can see:

XML
// rtti.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <malloc.h>
#include <stdlib.h>
#include <typeinfo>

int _tmain(int argc, _TCHAR* argv[])
{
    char buffer[256];
    char *p1=buffer;
    char *p2=(char *)malloc(512);
    char *p3=new char[1024];

    //std::type_info
    _tprintf(_T("typename %S\n"),typeid(buffer).name());
    _tprintf(_T("typename %S\n"),typeid(p1).name());
    _tprintf(_T("typename %S\n"),typeid(p2).name());
    _tprintf(_T("typename %S\n"),typeid(p3).name());

    free(p2);
    delete [] p3;
    return 0;
}
 
Share this answer
 
Comments
fvalerin 6-Mar-13 9:52am    
This solution only applies to C++, on C I get the error :

This header requires a C++ compiler ...

I know I tagged this question as C or C++, so my mistake. I did it because sometimes stuff on C++ works on C, but this is not the case.

Anyway I will use it when I need this on a C++ project.

Thank you very much for your time and for the try.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900