Click here to Skip to main content
14,667,264 members
Rate this:
Please Sign up or sign in to vote.
See more:
How can I discover if a variable is on Stack or Heap allocated(programatically)?

_CrtIsValidHeapPointer crashes if is a stack variable.

I want to make a method/define to use strcpy_s, but with sizeof() char* returns 4, then i use _msize, whetever when char cBuf[4], _msize don't work...

Something like this:

errno_t strcpyNew(char* c1, char* c2, int iSizeC1)
{
	if(iSizeC1 == 4 && _CrtIsValidHeapPointer((const void*)&c1))
		iSizeC1 = _msize(c1);

memset(c1,0,iSizeC1);

	if(iSizeC1 < strlen(c2))	
	{
		TRACE("ERROR.");
	}

	return strcpy_s(c1,iSizeC1,c2);
}

#define new_strcpy(c1, c2) strcpyNew(c1 , c2, sizeof(c1))


Error sample:

char cTeste4[4];

new_strcpy(cTeste4,"hi!");
Posted
Updated 6-Feb-12 5:16am
v2
Comments
Andreas Gieriet 6-Feb-12 12:41pm
   
I'm a bit puzzled. What do you try to achieve with that?
The macro is not working reliably since you can pass an array or a pointer, and the result will be different.

static void f(size_t size)
{
cout << size << "\n";
}
...
#define call(p) f(sizeof(p))
...
char buffer[40];
char *p = buffer;
call(buffer);
call(p);


And why you need to distinguish between heap and stack is not obvious to me.

Sorry for my ignorance ;-)

Cheers

Andi
   
I would really be interested to know why? Is it purely theoretical interest or anything else?

I have a strong impression that using programming technique based on such run-time diagnostic cannot be a good programming practice.
--SA
Omar.Pessoa 6-Feb-12 15:33pm
   
Hi SAKryukov, my problem is with strcpy_s, we have a lot of strcpy on source code, I need to simplify my conversion, but, samething like strcpy(char*, char*), but I cant resolve the size of all.
   
I don't see how could it help if you new if this is stack or heap. Here is how it would look:

enum MemoryType { Stack, Heap };
MemoryType GetMemoryType(void * pointer) {...}

if (GetMemoryType(myPointer) == Stack)
A(myPointer);
else
B(myPointer);

How A and B could be different depending on condition? Is my question clear?
--SA
Omar.Pessoa 7-Feb-12 7:51am
   
In our old project we have used just strcpy, now, we have to change to strcpy_s, sizeof doesnt returns size of char array in char*, just with char[n], but, I get size of array in this case with _msize().

I need it just to pass the size to my generic strcpy, like sample.

char cTest[10]; //strcpy(cTest,sizeof(cTest),"Hi this is a test");
char* cTest = new char[10]; //strcpy(cTest,_msize(cTest),"Hi this is a test");
   
Why not using std::string in all cases? Null-terminated strings are ineffective and error-prone, bad idea in first place...
--SA

Rate this:
Please Sign up or sign in to vote.

Solution 3

Either properly update the code or do nothing at all.

strycpy_s is already properly implemented. If by replacing strcpy by strcpy_s, the code does not compile, you should fix it manually.

Any other alternative is worst than doing nothing at all.
   
Rate this:
Please Sign up or sign in to vote.

Solution 1

In the call
_CrtIsValidHeapPointer((const void*)&c1))

, you're not using the passed pointer in the call, but instead the address of the temporary stack variable, passed to your function.

Note that in release mode _CrtIsValidHeapPointer is stubbed out. It only works in debug.
   
v3
Comments
Omar.Pessoa 6-Feb-12 11:39am
   
Ok, my problem is: I need use _msize but this crash on _CtrlIsValidHeapPointer to temporally stack variables.

Has some way to do what I think, using _msize to heap, and sizeof to temporally stack variables?

Or I want do call 2 methods? One to temporally stack and other to heap variables?
JackDingler 6-Feb-12 12:28pm
   
In your example, the value you're passing to _CrtIsValidHeapPointer will always be a stack variable. It's because you're taking the address on the variable passed on the stack, and not the value being passed.

Try _CrtIsValidHeapPointer((const void*) c1)) instead.
Rate this:
Please Sign up or sign in to vote.

Solution 2

_CrtIsValidHeapPointer() crashes because you are passing &c1. Using c1 should work. Note that _CrtIsValidHeapPointer() is only executed for debug builds.

You should also use sizeof(char *) when comparing the size to be independent from 32/64 bit builds.
   
Comments
Omar.Pessoa 6-Feb-12 11:47am
   
sizeof(char *) returns 4.
Jochen Arndt 6-Feb-12 11:55am
   
With 32-bit builds. Not with 64-bit builds.
Omar.Pessoa 6-Feb-12 11:58am
   

#include "stdafx.h"
#include
#include

int _tmain(int argc, _TCHAR* argv[])
{
char cTeste4[4];

int iSize4 = _msize(cTeste4);

char *cTeste = new char[10];

int iSize = _msize(cTeste);

return 0;
}


Has some way to do what I think, using _msize to heap, and sizeof to temporally stack variables?

Or I want do call 2 methods? One to temporally stack and other to heap variables?
Jochen Arndt 6-Feb-12 12:08pm
   
What do you want to say? That the first _msize() call fails? Of course, you are passing a pointer to a memory location that is not on the heap.
Omar.Pessoa 6-Feb-12 12:15pm
   
Ok, I know that, then I call sizeof().

Does someway to know progamatically how use sizeof() and how use _msize()?

I need to subscribe strcpy, using now the strcpy_s function.

Has you any Idea?
Jochen Arndt 6-Feb-12 12:23pm
   
_msize() is seldom used. And when it is used, mainly with debug builds. When using arrays, you know the size either from the fixed array size of local variables (stack) or by allocating memory from the heap (or stack using _alloca()). You already found strcpy_s(). And so it is usually done to track array sizes: Pass them as additional arguments.
Omar.Pessoa 6-Feb-12 12:26pm
   
Ok thanks.
JackDingler 6-Feb-12 12:34pm
   
Keep in mind that sizeof is not a runtime keyword. The value it returns is fixed and dependent on the size of the data type passed at compile time.

Jochen's comment is correct, don't use _msize in your code, instead track your sizes using an additional variable.
Rate this:
Please Sign up or sign in to vote.

Solution 4

your _CrtIsValidHeapPointer is suppose to get pointer just

call
_CrtIsValidHeapPointer((const void*)c1)
   

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




CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100