5

I'm working on my hobby project in c++, and want to test a continuous memory allocation for variables of different types, (Like array with variables of different types). How can i check if a specific memory address is available for use?

More Details:

Let's say we've got the following code: we have an integer int_var, (it doesn't matter in which memory address this variable seats), In order to allocate a variable of different type in the address right after the address of int_var i need to check if that address is available and then use it. i tried the following code:

int int_var = 5;
float* flt_ptr = (float*)(&int_var + (sizeof(int_var) / sizeof(int)));
// check if flt_ptr is successfully allocated
if (flt_ptr) { // successfully allocated
    // use that address
} else { // not successfully allocated
    cout << "ERROR";
}

The problem is: When i run the program, sometimes flt_ptr is successfully allocated and all right, and sometimes not - but when it is not successfully allocated it throws an exception that says "Read access violation ..." instead of printing "ERROR". Why is that? Maybe i missed something about checking if flt_ptr is successfully allocated? Or did something wrong? If so, How do i check if flt_ptr is successfully allocated before i use it?

Thanks!!

Daniel Rotnemer
  • 107
  • 3
  • 12
  • 1
    How about placement new? – macroland Jul 04 '19 at 09:31
  • 2
    *Why* do you want to "allocate a variable of different type in the address right after the address of `int_var`"? What would it bring you if it were possible? – Quentin Jul 04 '19 at 09:31
  • There are no "_certain_" (absolute) memory addresses. The memory your program gets from the OS is like a capsule, no one gets in or out, it only may increase / decrease in size. Even if you allocate memory to address "5", that memory allocation will (or at least might) be at a different position each time you run your program and it will certainly not be the 5th byte of your RAM or so. – nada Jul 04 '19 at 09:32
  • 4
    In no case is it “allocated and all right.” It may *seem* to work but it’s undefined behavior. If you need to do something like this then allocate a block of memory and use it however you want to. But you do need to allocate it first. And as was asked, why is this necessary? – Sami Kuhmonen Jul 04 '19 at 09:33
  • Note: you may use a `struct` with different variables. Then some compilers (gcc) allow to force a contiguous memory allocation. Not portable but simple. – Damien Jul 04 '19 at 09:38
  • 1
    It seems this is an [XY_Problem](http://xyproblem.info/), look at the comments OP gave in Babajan's answer: He's actually looking for a data structure to store different types in contiguous memory as i understand it. – nada Jul 04 '19 at 10:00
  • @Sami Kuhmonen, Thanks for your comment, Sorry, I want it to be like an array with variables of different types, In an array, the elements seat one after another, I want to implement an array that will contain ints, strings, chars, floats, ... example: `int i; // 0x00002000. char c; // 0x00002004`, i see this link for continuous allocation: https://cboard.cprogramming.com/c-programming/89456-allocate-variable-specific-address.html – Daniel Rotnemer Jul 04 '19 at 10:04
  • 2
    what is missing for clarifications is: why do you want to do this? – 463035818_is_not_an_ai Jul 04 '19 at 10:14
  • @DanielRotnemer I have the feeling that your question is lacking some important information: What _system/platform_ are you talking about? Seems like you're trying to do something on a microcontroller or a system without [MMU](https://en.wikipedia.org/wiki/Memory_management_unit)/[Virtual Memory](https://en.wikipedia.org/wiki/Virtual_memory), where the world looks a lot different wrt. memory management etc.. This might be important for a reasonable answer. (You could be accessing some fancy 8086 machine in real mode, who knows... :-)) – andreee Jul 04 '19 at 14:29
  • Thanks for help, I can't vote because my reputation is < 50 – Daniel Rotnemer Jul 04 '19 at 20:15

4 Answers4

4

This memory model you are assuming was valid back in DOS, where, in real mode, the memory was a continuous stream of bytes.

Now that we have paging (either in x86 or in x64), this is not possible. Therefore, you can make no assumptions on the existance of memory "near" memory.

You have to allocate properly, which means using C++ shared_ptr/unique_ptr/STL. Or, new/malloc the old (bad) way.

If you want variables to be one near the other, allocate the whole memory at once (via a struct, for example).

Michael Chourdakis
  • 10,345
  • 3
  • 42
  • 78
3

You can't, C++ memory model does not work like that.

The only valid pointers are those obtained by the '&' operator, those returned from 'new/malloc' and static arrays. There is no mechanism for checking if the memory address is (still) valid or whether the object has been destroyed or not existed there at all. So it is up to the programmer to manage the correctness of the pointers.

Because of the reasons above your program has undefined behavior.

if(pointer) only checks whether pointer==0, nothing more. Note that int n=5; int array[n]; is not valid C++ either. Not sure if you are using it, but if you do, don't.

Based on the comments, you want a heterogenous container. In that case use an array of unions or better std::array<std::variant<int,double,char, float...>> array;. Or std::vector if you need dynamic size.

C++ guarantees that arrays ([], malloc or new[]) are contiguous, but they only contain one type. In general, you cannot store float, double, int, char continuously together because of the alignment issues. The array above is continuous in terms of std::variant object, but its size will be at least the size of the largest type. So chars will not be packed together.

Quimby
  • 17,735
  • 4
  • 35
  • 55
  • 2
    _"In general, you cannot store `float, double, int, char` continuously together because of the alignment issues"_ - in general: but note that you still have `#pragma pack(1)` on most compilers (assuming a platform that can handle unaligned memory accesses). – andreee Jul 04 '19 at 12:48
1

That is not how you allocate memory. You need to do it properly using new.

See here.

Lehks
  • 2,582
  • 4
  • 19
  • 50
  • 1
    No, they need an automatic variable or a `std::unique_ptr`. – Quentin Jul 04 '19 at 09:29
  • 1
    "You need to do it properly using new." No that is not how you allocate memory in modern C++ ;). Raw `new` should be avoided in favour of smartpointers or standard container – 463035818_is_not_an_ai Jul 04 '19 at 09:31
  • I want to allocate address for my variable after the address of `int_var`, that isn't possible with the `new` operator that allocates whatever available address it finds. – Daniel Rotnemer Jul 04 '19 at 09:35
1

want to test a continuous memory allocation for variables of a different types

You may use a structure and declare required variables as members for continuous memory allocation for different datatypes.

For example:

struct eg_struct
{
           unsigned char abc;
           unsigned int  xyz;
}

Note that if required you may need to pack the structure.

Here there is no need to check whether memory is free or not.

Babajan
  • 364
  • 3
  • 5
  • 1
    Sorry, I want it to be like an array with variables of different types, In an array, the elements seat one after another, I want to implement an array that will contain ints, strings, chars, floats, ... example: `int i; // 0x00002000. char c; // 0x00002004`. etc. – Daniel Rotnemer Jul 04 '19 at 09:52