error C2375 - redefinition; different linkage

O

omnia neo

Hello,

I am trying to redirect the standard malloc and calloc defined in
stdlib.h to myown implementation MyMalloc amd MyCalloc. Following is
my impementation:

\\MyMemory.c
#include MyMemory.h /*implementation of MyMalloc() and MyCalloc()*/
#define malloc MyMalloc

But when i compile my code in VisualStudios I get following error:
...\VC\include\stdlib.h(601) : error C2375: 'MyMalloc' : redefinition;
different linkage
...\MyMemory.h(41) : see declaration of 'MyMalloc'

Please help me know how do I redirect the standard calls ?
 
S

Seebs

Please help me know how do I redirect the standard calls ?

You don't, portably.

If you want to try this, AFTER your includes of any standard headers,
try:
#undef malloc
#define malloc(x) MyMalloc(x)

Don't expect it to work...

-s
 
E

Eric Sosman

Hello,

I am trying to redirect the standard malloc and calloc defined in
stdlib.h to myown implementation MyMalloc amd MyCalloc. Following is
my impementation:

\\MyMemory.c
#include MyMemory.h /*implementation of MyMalloc() and MyCalloc()*/
#define malloc MyMalloc

But when i compile my code in VisualStudios I get following error:
..\VC\include\stdlib.h(601) : error C2375: 'MyMalloc' : redefinition;
different linkage
..\MyMemory.h(41) : see declaration of 'MyMalloc'

Please help me know how do I redirect the standard calls ?

As Seebs says, there's no portable way. With his recipe
you can arrange for malloc() calls *in your own source* to go
to MyMalloc(), but there's nothing you can do about calls that
are in library functions, or in any already-compiled functions
for which you lack source.

Also, you are very likely to come to grief if a memory area
allocated by MyMalloc() is freed with real free() or resized by
realloc(), so be sure to replace them with MyXxxx() versions.
Same for calloc(), plus any memory-related extra functions that
might be used -- mallinfo(), mallopt(), xmalloc(), ...

Finally, the error message you're getting probably has nothing
to do with all this and everything to do with an actual disagreement
in your actual code. But you didn't show us your actual code (not
even the #include line is from your actual code), so all we can give
you is the usual advice: "Fix the error on line forty-two." (The
message refers to line forty-one, but since forty-two is The Answer
it must be that the compiler counts lines from zero.) Cut your code
down to the smallest snippet that produces the error, post *all* of
that snippet *exactly* as you gave it to the compiler, and perhaps
someone will be able to see what's wrong.
 
I

ImpalerCore

You don't, portably.

If you want to try this, AFTER your includes of any standard headers,
try:
        #undef malloc
        #define malloc(x) MyMalloc(x)

Don't expect it to work...

I actually have had a use-case for it. But since you bring it up,
maybe I'm missing something?

\code snippet
#include <stdlib.h>

/* Hijack malloc */
#if defined(malloc)
# undef malloc
#endif
#define malloc(x) MyMalloc(x)

int main( void )
{
char* s = malloc( 20 );
}
\endcode

If malloc is a function prototype in stdlib.h, the '#if
defined(malloc)' won't find it since it's not a #define preprocessor
variable. When '#define malloc(x) MyMalloc(x)' is declared, the
preprocessor will covertly convert any further malloc names to
MyMalloc, as in converting 'char* s = malloc( 20 );' to the MyMalloc
wrapper 'char* s = MyMalloc( 20 );'. While this kind of wrapper
doesn't work for a complete replacement of malloc due to source and
library issues, there shouldn't be any gotchas for doing it this way
for a single file, right?

I have used the technique in the past to hijack malloc in a file that
implements a data structure when I want to enable more detailed
anaylsis of allocation associated with only part of the source in a
project. Here is an example that hopefully demonstrates the idea.

project.c
hash_table.h
hash_table.c
my_string.h
my_string.c

Use -DHASH_TABLE_ALLOC_LOG when compiling the project to enable a hash
table specific allocator wrapper. The wrapper itself uses malloc, but
it does some extra stuff on the side.

\code snippet ---hash_table.c---
....

#if defined(HASH_TABLE_ALLOC_LOG)
# if defined(malloc)
# undef malloc
# endif
# define malloc(x) log_malloc(x)
#endif

....
\endcode

The main advantage is that it gives a bit more granularity when
troubleshooting. I can enable the more expensive malloc for the hash
table but avoid the expense in my_string if it's trouble free. Do you
know of any particular problem using this kind of technique?

Best regards,
John D.
 
S

Seebs

While this kind of wrapper
doesn't work for a complete replacement of malloc due to source and
library issues, there shouldn't be any gotchas for doing it this way
for a single file, right?

I can't think of any, but the symbol is reserved for all uses, and I
am not inclined to expect that the compiler won't have Deeper Magic to
let it outsmart me.
The main advantage is that it gives a bit more granularity when
troubleshooting. I can enable the more expensive malloc for the hash
table but avoid the expense in my_string if it's trouble free. Do you
know of any particular problem using this kind of technique?

Just general paranoia. :)

-s
 
E

Eric Sosman

I actually have had a use-case for it. But since you bring it up,
maybe I'm missing something?

\code snippet
#include<stdlib.h>

/* Hijack malloc */
#if defined(malloc)
# undef malloc
#endif

No need for the test; it's perfectly all right to #undef
something that isn't defined as a macro.
#define malloc(x) MyMalloc(x)

`#define malloc MyMalloc' would be better, because it would
also intercept things like

char *p = (malloc)(20);
and
void *(*fptr)(size_t) = malloc;
char *q = fptr(20);

Sometimes you want to use parens or pointers to override the
macro substitution, but I opine that you do *not* want to mix
and match different memory manager implementations in the same
file -- usually, not even in the same program.
int main( void )
{
char* s = malloc( 20 );

This is an error, both in C99 and C90, because there's
no declaration of MyMalloc() in sight. Note that <stdlib.h>
declared malloc(), but did so under the actual name `malloc'
and not under the preprocessor-fudged name MyMalloc().
 
I

ImpalerCore

     No need for the test; it's perfectly all right to #undef
something that isn't defined as a macro.

So it doesn't matter whether or not malloc is a function proto or a
macro wrapper. Sounds good to me.
     `#define malloc MyMalloc' would be better, because it would
also intercept things like

        char *p = (malloc)(20);
and
        void *(*fptr)(size_t) = malloc;
        char *q = fptr(20);

Interesting use cases, haven't run into those issues.
Sometimes you want to use parens or pointers to override the
macro substitution, but I opine that you do *not* want to mix
and match different memory manager implementations in the same
file -- usually, not even in the same program.

Yeah, in all my cases, hijacking malloc to implement some extra
functionality uses malloc internally. I haven't played with other
memory managers.

Sometimes I also change the macro arguments, as in the common
construct

#define malloc(size) more_log_malloc( (size), __FILE__, __LINE__ )
     This is an error, both in C99 and C90, because there's
no declaration of MyMalloc() in sight.  Note that <stdlib.h>
declared malloc(), but did so under the actual name `malloc'
and not under the preprocessor-fudged name MyMalloc().

Yeah, I forgot that. Thanks for the comments.

Best regards,
John D.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,050
Latest member
AngelS122

Latest Threads

Top