Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

64bit architecture - character pointer truncated while returning from function

Environment:

Windows x64 bit with 5GB RAM. My binary is a 64bit one built with compiler of version - "Microsoft (R) C/C++ Optimizing Compiler Version 14.00.50727.762 for x64"

Environment setting:

Microsoft suggests to set the below registry key to test 64 bit applications and I have set the same in my box. The problem doesn't occur if i don't set the below registry because the program is placed at a low address. The same registry key is mentioned in the discussion - As a programmer, what do I need to worry about when moving to 64-bit windows?

To force allocations to allocate from higher addresses before lower addresses for testing purposes, specify MEM_TOP_DOWN when calling VirtualAlloc or set the following registry value to 0x100000:

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Memory Management\AllocationPreference

Sample code:

char *alloc_str()
{
    char *temp;
    temp = (char *) malloc(60);
    /* copy some data to temp */
    return temp;
}

main()
{
    char *str;
    str = (char *)alloc_str();
}

Analysis:

malloc returns address 0x000007fffe999b40 which is stored in temp but when the pointer is returned to main(), str gets only the second half - 0xfffffffffe999b40 and I am not able to access the data at that location.

like image 436
yogishaj Avatar asked Jan 20 '11 15:01

yogishaj


2 Answers

Two points about style, which could help to diagnose this kind of problems. As you use malloc I suppose that it is compiled as a C program. In that case, do not typecast when it is not necessary. Excessive typecasts may suppress the warnings telling you that you have not correctly declared your functions. If there is no prototype and the function definition is in another module then your call str = (char *)alloc_str(); will suppress the warning that the function is used without declaration and the default declaration of C will be used, i.e. all parameter and return value will be considered as int . Same thing with the malloc, if you forgot the right include, your typecast will suppress the warning and the compiler will assume the function returns an int. This might be already the cause of the truncation. Another point, in C, an empty parameter list is declared with (void) not () which has another meaning (unspecified parameters). These are 2 points that differ between C and C++.

like image 121
Patrick Schlüter Avatar answered Sep 27 '22 21:09

Patrick Schlüter


The registry setting you refer to selects top-down memory allocation. You state that this setting will "place program in high address space". It won't do that. What this does is force the Windows memory manager to allocate memory from the top of the address space.

What's more since you are running under 64 bit Windows, I fail to see where PAE comes into play. That would be something used on a 32 bit platform.

I would guess that you are compiling a 32 bit app and so inevitably your pointers are 32 bits wide. But that is only a guess due to the lack of information.

In short your question is impossible to answer because you haven't told us what you are doing.

like image 31
David Heffernan Avatar answered Sep 27 '22 19:09

David Heffernan