0

I mean to give pointer to variable in struct\memory and then give it to some function and it'll give me pointer to the start of the struct\memory. There is a function that does it?

To understand this question:

char* ptr=((char*)malloc(12))+3;
//MemStart(ptr) == ptr-3

MemStart'll be the function that'll give that result in the code.

8
  • 2
    the pointer doesn't carry enough information itself Commented Sep 30, 2012 at 6:32
  • @Cheersandhth.-Alf Like _msize that gives the size of the allocation that the pointer itself doesn't have size field in it. Couldn't here be MemStart too? Commented Sep 30, 2012 at 6:34
  • 1
    _msize isn't part of standard C and frankly, as a fresh beginner you will just create endless trouble for yourself if you try to use things with names that start with underscore (they're internal implementation details). also, after adding 3 to the pointer you have discarded the information about where the memory block begins. i'm not sure if your expression will even compile, but i gather that the intent is to increase the pointer address by 3. Commented Sep 30, 2012 at 6:38
  • @DividedByZero There could definitely be, apparently jist there isn't. Commented Sep 30, 2012 at 6:38
  • Your example might be char *c = (new char[12])+3; and internally C++ knows the size of dynamically allocated arrays (to be able to delete[] them). Commented Sep 30, 2012 at 6:55

3 Answers 3

3

Unless there is something specific to that structure's representation in memory (such as it always starts with the bytes 0xff, 0xff), there is no way to determine where a particular structure or array starts. Modern architectures are Von Neuman machines, meaning memory has no inherent meaning.

Note that many architectures have alignment issues or optimizations, meaning structures or arrays may need to start on 16-bit, 32-bit or 64-bit word boundaries, but these are architecture specific.

[Edit: Added the following]

The library may introduce guard bytes at the start or end of the allocated block of memory or fill memory with known constants to look for buffer overflows or errant pointers. However, these are usually omitted in release mode and, even if they are present, may also be valid data.

You could inspect the memory allocation table for dynamically allocated memory but the array/struct could be allocated on the stack rather than the heap. Also, what happens if you have a structure within an array? Which value does it return? If you want to restrict it to just dynamically allocated memory where you want the start of whatever memory was allocated only, Basile has a great answer.

Sign up to request clarification or add additional context in comments.

2 Comments

I tested it ,but it ends with FDFDFDFD not 0xff, 0xff. You mistaked or each computer is different?
The library may introduce guard bytes (see en.wikipedia.org/wiki/Guard_byte) at the start or end of the allocated block of memory or fill memory with known constants to look for buffer overflows or errant pointers. However, these are usually omitted in release mode and, even if they are present, may also be valid data. You could inspect the memory allocation table for dynamically allocated memory but the array/struct could be allocated on the stack rather than the heap and what happens if you have a structure within an array? I know of no sure way of achieving this.
2

Most malloc implementations don't provide what you want (the starting address of a dynamically allocated block, given some internal pointer to it). And the standards don't require anything like that. So you may want to use both pointer to base, and offset (perhaps packing them inside some C++ class fat_pointer with operator* and operator-> giving the illusion of pointers, etc, etc).

You could of course re-implement your own malloc above operating system memory segment allocation (i.e. mmap(2) on Linux or Posix) and de-allocation munmap(2) primitive syscalls.

You could also have your specialized allocator; it might allocate your zones with a large power-of-two alignment (e.g. 256 or 4096 bytes) using posix_memalign, then use bits manipulation on the intptr_t cast of your pointer.

Notice that implementing any serious memory allocator means caring about unportable details of your operating system and architecture (alignment, ...).

You could also use Boehm's conservative garbage collector, that is use GC_malloc instead of malloc (and don't bother GC_free-ing your dynamic data); then you have the GC_base function which does exactly what you want:

/* Return a pointer to the base (lowest address) of an object given   */
/* a pointer to a location within the object.                         */
/* I.e. map an interior pointer to the corresponding bas pointer.     */
/* Note that with debugging allocation, this returns a pointer to the */
/* actual base of the object, i.e. the debug information, not to      */
/* the base of the user object.                                       */
/* Return 0 if displaced_pointer doesn't point to within a valid      */
/* object.                                                            */
/* Note that a deallocated object in the garbage collected heap       */
/* may be considered valid, even if it has been deallocated with      */
/* GC_free.                                                           */
GC_API void * GC_base(void * displaced_pointer);

3 Comments

I am creating GC alright for this question. What a coincidence. But I can't use GC for GC.
Every GC pointer in struct has pointer in it to the master struct. I want to optimize this pointer I want only pointer to the object. (I need to know where the master struct exists at)
0

You can use the offsetof() macro from <cstddef>:

#include <cstddef>
#include <iostream>

using namespace std;

typedef struct
{
  int a;
  int b;
} S;

int main()
{
  S s = { 1, 2 };

  cout << "address of s:" << &s << endl;
  cout << "address of s.a:" << &s.a << endl;
  cout << "address of s.b:" << &s.b << endl;

  int* pb = &s.b;
  S* ps = (S*)((char*)pb - offsetof(S, b));

  cout << "ps:" << ps << endl;

  return 0;
}

Output (ideone):

address of s:0xbffd266c
address of s.a:0xbffd266c
address of s.b:0xbffd2670
ps:0xbffd266c

2 Comments

I want to put random pointer, not something that I know what it is and etc.
In that case you generally can't do it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.