Why is there no 'aligned_realloc' on most platforms? - c++

MSVC has its own non-standard functions _aligned_malloc, _aligned_realloc and _aligned_free.
C++17 and C11 have introduced (std::)aligned_alloc, results of which can be deallocated with free or realloc. But realloc cannot be used to actually reallocate memory returned by aligned_alloc, since it does not take an alignment parameter and thus cannot guarantee that the returned pointer will be properly aligned.
I can't even find any non-standard extensions that could reallocate aligned memory (preserving its alignment) on platforms other than Microsoft Windows / Visual C++.
Am I searching for it wrong, or is there indeed no _aligned_realloc alternative on POSIX and other platforms?
If so,
Why?
What can be used instead on those platforms? Is there nothing better than calling aligned_alloc with the new alignment, and then doing memcpy and freeing the old pointer on success?

While POSIX (which tends to act as a lowest common denominator on most platforms) does not have an aligned_realloc, it does have aligned_alloc and memcpy. Therefore you can very easily implement your own aligned_realloc which is guaranteed to work on any reasonably posix compliant platform using these. However, note that there is not a posix standard method to get the size of a malloc'd region of memory. You'll have to track that yourself.
EDIT: have a bit of free time so I'm extending this to answer the most common criticism
What I've proposed is, as the astute commenter will note, not how realloc works internally.
Under the hood, your standard realloc implementation will do its damnedest to avoid preforming the above behavior of mallocing and memcpying with a free afterwards. It will try to use one of two behaviors before resorting to the fallback.
1) If the new size is smaller than the old size, it will resize the memory in place, avoiding having to allocate, copy, or free.
2) if the new size is greater than the old size, it will (in simplified terms) see if there is free memory of sufficient size adjacent, and if so it will gobble up that memory and resize in place. If not, it resorts to the fallback.
I proposed a naive approach, because I figured most people asking this question wouldn't want to have to implement their own malloc implementation. (Though I highly suggest doing such for educational purposes)
Hope this satisfies any complaints!

Intel Math Kernel Library (free; available for Windows, Linux and macOS) ver. >= 11.3.1 has mkl_realloc that preserves alignment:
Simple example:
auto p1 = std::aligned_alloc(1024, 1000);
std::cout << reinterpret_cast<std::uintptr_t>(p1) % 1024 << std::endl;
auto p2 = std::realloc(p1, 2000);
std::cout << reinterpret_cast<std::uintptr_t>(p2) % 1024 << std::endl;
auto p3 = std::realloc(p2, 3000);
std::cout << reinterpret_cast<std::uintptr_t>(p3) % 1024 << std::endl;
auto q1 = mkl_malloc(1000, 1024);
std::cout << reinterpret_cast<std::uintptr_t>(q1) % 1024 << std::endl;
auto q2 = mkl_realloc(q1, 2000);
std::cout << reinterpret_cast<std::uintptr_t>(q2) % 1024 << std::endl;
auto q3 = mkl_realloc(q2, 3000);
std::cout << reinterpret_cast<std::uintptr_t>(q3) % 1024 << std::endl;
The output on my machine is:
0
784
784
0
0
0

Just a simple cross-post, from the following two, it should not be too hard to create an aligned_realloc function:
#include <stdlib.h>
#include <assert.h>
void* seriously_aligned_malloc(size_t alignment, size_t size) {
assert(alignment<=255);
char* allocated = (char*)malloc(size + alignment);
unsigned char extraspace = (unsigned char)(alignment - (size_t)(allocated+alignment) % alignment);
char* ptr = allocated + extraspace;
unsigned char* extraspaceptr = (unsigned char*)(ptr - 1);
*extraspaceptr = extraspace;
return ptr;
}
void seriously_aligned_free(void* p) {
char* ptr = (char*)p;
unsigned char* extraspaceptr = (unsigned char*)(ptr - 1);
unsigned char extraspace = *extraspaceptr;
char* allocated = ptr - extraspace;
free(allocated);
}
I believe there is also information at:
Is there a linux equivalent of _aligned_realloc

Related

Regarding shared_ptr reference count block

I had 2 questions regarding the std::shared_ptr control block:
(1) Regarding size:
How can I programatically find the exact size of the control block for a std::shared_ptr?
(2) Regarding logic:
Additionally, boost::shared_ptr mentions that they are completely lock-free with respect to changes in the control block.(Starting with Boost release 1.33.0, shared_ptr uses a lock-free implementation on most common platforms.) I don't think std::shared_ptr follows the same - is this planned for any future C++ version? Doesn't this also mean that boost::shared_ptr is a better idea for multithreaded cases?
(1) Regarding size: How can I programatically find the exact size of the control block for a std::shared_ptr?
There is no way. It's not directly accessible.
(2) Regarding logic: Additionally, boost::shared_ptr mentions that they are completely lock-free with respect to changes in the control block.(Starting with Boost release 1.33.0, shared_ptr uses a lock-free implementation on most common platforms.) I don't think std::shared_ptr follows the same - is this planned for any future C++ version? Doesn't this also mean that boost::shared_ptr is a better idea for multithreaded cases?
Absolutely not. Lock-free implementations are not always better than implementations that use locks. Having an additional constraint, at best, doesn't make the implementation worse but it cannot possibly make the implementation better.
Consider two equally competent programmers each doing their best to implement shared_ptr. One must produce a lock-free implementation. The other is completely free to use their best judgment. There is simply no way the one that must produce a lock-free implementation can produce a better implementation all other things being equal. At best, a lock-free implementation is best and they'll both produce one. At worse, on this platform a lock-free implementation has huge disadvantages and one implementer must use one. Yuck.
The control block is not exposed. In implementations I have read it is dynamic in size to store the deleter contiguously (and/or, in the case of make shared, the object itself).
In general it contains at least 3 pointer-size fields - weak, strong count, and deleter invoker.
At least one implementation relies on RTTI; others do not.
Operations on the count use atomic operations in the implementations I have read; note that C++ does not require atomic operatins to all be lock free (I believe a platform that doesn't have pointer-size lock-free operations can be a conforming C++ platform).
Their state is are consistent with each other and themselves, but no attempt to make them consistent with object state occurs. This is why using raw shared ptrs as copy on write pImpls may be error prone on some platforms.
(1)
Of course it is best to check implementation, however you still may make some checks from your program.
Control block is allocated dynamically, so to determine its size you may overload new operator.
Then what you may also check is if std::make_shared provides you with some optimization of control block size.
In proper implementation I would expect that this will make two allocations (objectA and control block):
std::shared_ptr<A> i(new A());
However this will make only one allocation (and then objectA initialized with placement new):
auto a = std::make_shared<A>();
Consider following example:
#include <iostream>
#include <memory>
void * operator new(size_t size)
{
std::cout << "Requested allocation: " << size << std::endl;
void * p = malloc(size);
return p;
}
class A {};
class B
{
int a[8];
};
int main()
{
std::cout << "Sizeof int: " << sizeof(int) << ", A(empty): " << sizeof(A) << ", B(8 ints): " << sizeof(B) << std::endl;
{
std::cout << "Just new:" << std::endl;
std::cout << "- int:" << std::endl;
std::shared_ptr<int> i(new int());
std::cout << "- A(empty):" << std::endl;
std::shared_ptr<A> a(new A());
std::cout << "- B(8 ints):" << std::endl;
std::shared_ptr<B> b(new B());
}
{
std::cout << "Make shared:" << std::endl;
std::cout << "- int:" << std::endl;
auto i = std::make_shared<int>();
std::cout << "- A(empty):" << std::endl;
auto a = std::make_shared<A>();
std::cout << "- B(8 ints):" << std::endl;
auto b = std::make_shared<B>();
}
}
The output I received (of course it is hw architecture and compiler specific):
Sizeof int: 4, A(empty): 1, B(8 ints): 32
Just new:
- int:
Requested allocation: 4
Requested allocation: 24
First allocation for int - 4 bytes, next one for control block - 24 bytes.
- A(empty):
Requested allocation: 1
Requested allocation: 24
- B(8 ints):
Requested allocation: 32
Requested allocation: 24
Looks that control block is (most probably) 24 bytes.
Here is why to use make_shared:
Make shared:
- int:
Requested allocation: 24
Only one allocation, int + control block = 24 bytes, less then before.
- A(empty):
Requested allocation: 24
- B(8 ints):
Requested allocation: 48
Here one could expect 56 (32+24), but it looks that implementation is optimized. If you use make_shared - pointer to actual object is not needed in control block and its size is only 16 bytes.
Other possibility to check the size of control block is to:
std::cout<< sizeof(std::enable_shared_from_this<int>);
In my case:
16
So I would say that the size of control block in my case is 16-24 bytes, depending on how it was created.

Strict aliasing, and alignment questions when partitioning memory

My goal is to allocate a single chunk of memory and then partition it into smaller arrays of different types. I have a few questions about the code I've written here:
#include <iostream>
#include <cstdint>
#include <cstdlib>
int main() {
constexpr std::size_t array_count = 5;
constexpr std::size_t elements_size = sizeof(std::uint32_t) + sizeof(std::uint16_t);
void* const pv = std::calloc(array_count, elements_size);
//Partition the memory. p32 array starts at pv, p16 array starts after the 20 byte buffer for the p32 array.
std::uint32_t* const p32 = (std::uint32_t *) pv;
std::uint16_t* const p16 = (std::uint16_t *)((char *) pv + sizeof(std::uint32_t) * array_count);
//Initialize values.
for(std::size_t i = 0; i < array_count; ++i) {
p32[i] = i;
p16[i] = i * 2;
}
//Read them back.
for(std::size_t i = 0; i < array_count; ++i) {
std::cout << p32[i] << std::endl;
std::cout << p16[i] << std::endl;
std::cout << std::endl;
}
std::free(pv);
}
Does this code violate c++'s strict aliasing rules? I'm having trouble finding resources on aliasing when casting pointers from a malloc or calloc call. The p32 and p16 pointers should never overlap.
If I reverse the positioning of the two arrays where p16 started at pv, and p32 had a 10 byte offset from pv this could cause a segfault because uint32_t is aligned to the 4 byte boundary pv + 10 could be on the 2 byte boundary, right?
Is this program unsafe, or introduce any undefined behavior that I'm missing in general? I get the expected output on my local machine, but of course that doesn't mean my code is correct.
Yes, the program is UB. When you do this:
for(std::size_t i = 0; i < array_count; ++i) {
p32[i] = i;
p16[i] = i * 2;
}
There are no uint32_t or uint16_t objects that p32 or p16 point to. calloc just gives you bytes, not objects. You can't just reinterpret_cast objects into existence. On top of that, indexing is only defined for arrays, and p32 does not point to an array.
To make it well defined, you'd have to create an array object. However, placement-new for arrays is broken, so you're left with manually initializing a bunch of uint32_ts like:
auto p32 = reinterpret_cast<uint32_t*>(pv);
for (int i = 0; i < array_count; ++i) {
new (p32+i) uint32_t; // NB: this does no initialization, but it does satisfy
// [intro.object] in actually creating an object
}
This would then run into a separate issue: CWG 2182. Now we have array_count uint32_ts, but we don't have a uint32_t[array_count] so indexing is still UB. Basically, there's just no way in purely-by-the-letter-of-the-standard C++ to write this. See also my similar question on the topic.
That said, the amount of code that does this in the wild is tremendous and every implementation will allow you to do it.
I am only going to address Strict Aliasing part of the question.
C++ standard talks very little about malloc - mostly mentions it has semantic defined in C. In strict reading of C++ standard, there is no aliasing rule violation because there is no object which is aliased - in C++, lifetime of the object begins after it has been constructed, and no object has been constructed by malloc call.
As a result, this is something which is simply unspecified by Standard (as opposed by undefined).
No it's just normal cast of malloc return value and handling allocated memory. You can reinterpret these bytes to whatever datatype you want. Until you touch memory behind borders of allocated block.
No
I know you are just asking and trying, but you should allocate memory typically.
std::uint32_t* const p32 = std::calloc(array_count, sizeof(std::uint32_t));
std::uint16_t* const p16 = std::calloc(array_count, sizeof(std::uint16_t));
Is this program unsafe?
In your example, I think there is no problem with exceptions at all, but I suppose you intend to use it in another context. If your code throws an exception, you probably are going to leak some memory.
Do you really need to use calloc/free? In the cppcore guidelines you can find some guidelines about resource management in C++:
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#S-resource
For instance, R10 and R11 say "not to call explicitly malloc/calloc/free, new/delete": https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Rr-mallocfree
Only if you are doing something that really needs very low level code, you need to call new and delete explicitly, but the C++ way is to encapsulate all this calls inside a class, so the user of the class doesn't need to call explicitly new and delete.
But if you are not doing some low level stuff, have you consider to use std::array<>? or std::vector?

How many indirection level I can have in c++? [duplicate]

How many pointers (*) are allowed in a single variable?
Let's consider the following example.
int a = 10;
int *p = &a;
Similarly we can have
int **q = &p;
int ***r = &q;
and so on.
For example,
int ****************zz;
The C standard specifies the lower limit:
5.2.4.1 Translation limits
276 The implementation shall be able to translate and execute at least one program that contains at least one instance of every one of the following limits: [...]
279 — 12 pointer, array, and function declarators (in any combinations) modifying an
arithmetic, structure, union, or void type in a declaration
The upper limit is implementation specific.
Actually, C programs commonly make use of infinite pointer indirection. One or two static levels are common. Triple indirection is rare. But infinite is very common.
Infinite pointer indirection is achieved with the help of a struct, of course, not with a direct declarator, which would be impossible. And a struct is needed so that you can include other data in this structure at the different levels where this can terminate.
struct list { struct list *next; ... };
now you can have list->next->next->next->...->next. This is really just multiple pointer indirections: *(*(..(*(*(*list).next).next).next...).next).next. And the .next is basically a noop when it's the first member of the structure, so we can imagine this as ***..***ptr.
There is really no limit on this because the links can be traversed with a loop rather than a giant expression like this, and moreover, the structure can easily be made circular.
Thus, in other words, linked lists may be the ultimate example of adding another level of indirection to solve a problem, since you're doing it dynamically with every push operation. :)
Theoretically:
You can have as many levels of indirections as you want.
Practically:
Of course, nothing that consumes memory can be indefinite, there will be limitations due to resources available on the host environment. So practically there is a maximum limit to what an implementation can support and the implementation shall document it appropriately. So in all such artifacts, the standard does not specify the maximum limit, but it does specify the lower limits.
Here's the reference:
C99 Standard 5.2.4.1 Translation limits:
— 12 pointer, array, and function declarators (in any combinations) modifying an
arithmetic, structure, union, or void type in a declaration.
This specifies the lower limit that every implementation must support. Note that in a footenote the standard further says:
18) Implementations should avoid imposing fixed translation limits whenever possible.
As people have said, no limit "in theory". However, out of interest I ran this with g++ 4.1.2, and it worked with size up to 20,000. Compile was pretty slow though, so I didn't try higher. So I'd guess g++ doesn't impose any limit either. (Try setting size = 10 and looking in ptr.cpp if it's not immediately obvious.)
g++ create.cpp -o create ; ./create > ptr.cpp ; g++ ptr.cpp -o ptr ; ./ptr
create.cpp
#include <iostream>
int main()
{
const int size = 200;
std::cout << "#include <iostream>\n\n";
std::cout << "int main()\n{\n";
std::cout << " int i0 = " << size << ";";
for (int i = 1; i < size; ++i)
{
std::cout << " int ";
for (int j = 0; j < i; ++j) std::cout << "*";
std::cout << " i" << i << " = &i" << i-1 << ";\n";
}
std::cout << " std::cout << ";
for (int i = 1; i < size; ++i) std::cout << "*";
std::cout << "i" << size-1 << " << \"\\n\";\n";
std::cout << " return 0;\n}\n";
return 0;
}
Sounds fun to check.
Visual Studio 2010 (on Windows 7), you can have 1011 levels before getting this error:
fatal error C1026: parser stack overflow, program too complex
gcc (Ubuntu), 100k+ * without a crash ! I guess the hardware is the limit here.
(tested with just a variable declaration)
There is no limit, check example at Pointers :: C Interview Questions and Answers.
The answer depends on what you mean by "levels of pointers." If you mean "How many levels of indirection can you have in a single declaration?" the answer is "At least 12."
int i = 0;
int *ip01 = & i;
int **ip02 = & ip01;
int ***ip03 = & ip02;
int ****ip04 = & ip03;
int *****ip05 = & ip04;
int ******ip06 = & ip05;
int *******ip07 = & ip06;
int ********ip08 = & ip07;
int *********ip09 = & ip08;
int **********ip10 = & ip09;
int ***********ip11 = & ip10;
int ************ip12 = & ip11;
************ip12 = 1; /* i = 1 */
If you mean "How many levels of pointer can you use before the program gets hard to read," that's a matter of taste, but there is a limit. Having two levels of indirection (a pointer to a pointer to something) is common. Any more than that gets a bit harder to think about easily; don't do it unless the alternative would be worse.
If you mean "How many levels of pointer indirection can you have at runtime," there's no limit. This point is particularly important for circular lists, in which each node points to the next. Your program can follow the pointers forever.
It's actually even funnier with pointer to functions.
#include <cstdio>
typedef void (*FuncType)();
static void Print() { std::printf("%s", "Hello, World!\n"); }
int main() {
FuncType const ft = &Print;
ft();
(*ft)();
(**ft)();
/* ... */
}
As illustrated here this gives:
Hello, World!
Hello, World!
Hello, World!
And it does not involve any runtime overhead, so you can probably stack them as much as you want... until your compiler chokes on the file.
There is no limit. A pointer is a chunk of memory whose contents are an address.
As you said
int a = 10;
int *p = &a;
A pointer to a pointer is also a variable which contains an address of another pointer.
int **q = &p;
Here q is pointer to pointer holding the address of p which is already holding the address of a.
There is nothing particularly special about a pointer to a pointer. So there is no limit on chain of poniters which are holding the address of another pointer.
ie.
int **************************************************************************z;
is allowed.
Every C++ developer should have heard of the (in)famous Three star programmer.
And there really seems to be some magic "pointer barrier" that has to be camouflaged.
Quote from C2:
Three Star Programmer
A rating system for C-programmers. The more indirect your pointers are (i.e. the more "*" before your variables), the higher your reputation will be. No-star C-programmers are virtually non-existent, as virtually all non-trivial programs require use of pointers. Most are one-star programmers. In the old times (well, I'm young, so these look like old times to me at least), one would occasionally find a piece of code done by a three-star programmer and shiver with awe.
Some people even claimed they'd seen three-star code with function pointers involved, on more than one level of indirection. Sounded as real as UFOs to me.
Note that there are two possible questions here: how many levels of pointer indirection we can achieve in a C type, and how many levels of pointer indirection we can stuff into a single declarator.
The C standard allows a maximum to be imposed on the former (and gives a minimum value for that). But that can be circumvented via multiple typedef declarations:
typedef int *type0;
typedef type0 *type1;
typedef type1 *type2; /* etc */
So ultimately, this is an implementation issue connected to the idea of how big/complex can a C program be made before it is rejected, which is very compiler specific.
I'd like to point out that producing a type with an arbitrary number of *'s is something that can happen with template metaprogramming. I forget what I was doing exactly, but it was suggested that I could produce new distinct types that have some kind of meta maneuvering between them by using recursive T* types.
Template Metaprogramming is a slow descent into madness, so it is not necessary to make excuses when generating a type with several thousand level of indirection. It's just a handy way to map peano integers, for example, onto template expansion as a functional language.
Rule 17.5 of the 2004 MISRA C standard prohibits more than 2 levels of pointer indirection.
There isn't such a thing like real limit but limit exists. All pointers are variables that are usually storing in stack not heap. Stack is usually small (it is possible to change its size during some linking). So lets say you have 4MB stack, what is quite normal size. And lets say we have pointer which is 4 bytes size (pointer sizes are not the same depending on architecture, target and compiler settings).
In this case 4 MB / 4 b = 1024 so possible maximum number would be 1048576, but we shouldn't ignore the fact that some other stuff is in stack.
However some compilers may have maximum number of pointer chain, but the limit is stack size. So if you increase stack size during linking with infinity and have machine with infinity memory which runs OS which handles that memory so you will have unlimited pointer chain.
If you use int *ptr = new int; and put your pointer into heap, that is not so usual way limit would be heap size, not stack.
EDIT Just realize that infinity / 2 = infinity. If machine has more memory so the pointer size increases. So if memory is infinity and size of pointer is infinity, so it is bad news... :)
It depends on the place where you store pointers. If they are in stack you have quite low limit. If you store it in heap, you limit is much much much higher.
Look at this program:
#include <iostream>
const int CBlockSize = 1048576;
int main()
{
int number = 0;
int** ptr = new int*[CBlockSize];
ptr[0] = &number;
for (int i = 1; i < CBlockSize; ++i)
ptr[i] = reinterpret_cast<int *> (&ptr[i - 1]);
for (int i = CBlockSize-1; i >= 0; --i)
std::cout << i << " " << (int)ptr[i] << "->" << *ptr[i] << std::endl;
return 0;
}
It creates 1M pointers and at the shows what point to what it is easy to notice what the chain goes to the first variable number.
BTW. It uses 92K of RAM so just imagine how deep you can go.

MSVC Access Violation when setting array elements

I have been struggling in finding an explanation to an error I get in the following code:
#include <stdlib.h>
int main() {
int m=65536;
int n=65536;
float *a;
a = (float *)malloc(m*n*sizeof(float));
for (int i = 0; i < m; i++){
for (int j = 0; j < n; j++){
a[i*n + j] = 0;
}
}
return 0;
}
Why do I get an "Access Violation" Error when executing this program?
The memory allocation is succesful, the problem is in the nested for loops at some iteration count. I tried with a smaller value of m&n and the program works.
Does this mean I ran out of memory?
The problem is that m*n*sizeof(float) is likely an overflow, resulting in a relatively small value. Thus the malloc works, but it does not allocate as much memory as you're expecting and so you run off the end of the buffer.
Specifically, if your ints are 32 bits wide (which is common), then 65336 * 65336 is already an overflow, because you would need at least 33 bits to represent it. Signed integer overflows in C++ (and I believe in C) result in undefined behavior, but a common result is that the most significant bits are lopped off, and you're left with the lower ones. In your case, that gives 0. That's then multiplied by sizeof(float), but zero times anything is still zero.
So you've tried to allocate 0 bytes. It turns out that malloc will let you do that, and it will give back a valid pointer rather than a null pointer (which is what you'd get if the allocation failed). (See Edit below.)
So you have a valid pointer, but it's not valid to dereference it. That fact that you are able to dereference it at all is a side-effect of the implementation: In order to generate a unique address that doesn't get reused, which is what malloc is required to do when you ask for 0 bytes, malloc probably allocated a small-but-non-zero number of bytes. When you try to reference far enough beyond those, you'll typically get an access violation.
EDIT:
It turns out that what malloc does when requesting 0 bytes may depend on whether you're using C or C++. In the old days, the C standard required a malloc of 0 bytes to return a unique pointer as a way of generating "special" pointer values. In modern C++, a malloc of 0 bytes is undefined (see Footnote 35 in Section 3.7.4.1 of the C++11 standard). I hadn't realized malloc's API had changed in this way when I originally wrote the answer. (I love it when a newbie question causes me to learn something new.) VC++2013 appears to preserve the older behavior (returning a unique pointer for an allocation of 0 bytes), even when compiling for C++.
You are victim of 2 problems.
First the size calculation:
As some people have pointned out, you are exceeding the range of size_t. You can verify the size that you are trying to allocate with this code:
cout << "Max size_t is: " << SIZE_MAX<<endl;
cout << "Max int is : " << INT_MAX<<endl;
long long lsz = static_cast<long long>(m)*n*sizeof(float); // long long to see theoretical result
size_t sz = m*n*sizeof(float); // real result with overflow as will be used by malloc
cout << "Expected size: " << lsz << endl;
cout << "Requested size_t:" << sz << endl;
You'll be surprised but with MSVC13, you are asking 0 bytes because of the overflow (!!). You might get another number with a different compiler (resulting in a lower than expected size).
Second, malloc() might return a problem pointer:
The call for malloc() could appear as successfull because it does not return nullptr. The allocated memory could be smaller than expected. And even requesting 0 bytes might appear as successfull, as documented here: If size is zero, the return value depends on the particular library implementation (it may or may not be a null pointer), but the returned pointer shall not be dereferenced.
float *a = reinterpret_cast<float*>(malloc(m*n*sizeof(float))); // prefer casts in future
if (a == nullptr)
cout << "Big trouble !"; // will not be called
Alternatives
If you absolutely want to use C, prefer calloc(), you'll get at least a null pointer, because the function notices that you'll have an overflow:
float *b = reinterpret_cast<float*>(calloc(m,n*sizeof(float)));
But a better approach would be to use the operator new[]:
float *c = new (std::nothrow) float[m*n]; // this is the C++ way to do it
if (c == nullptr)
cout << "new Big trouble !";
else {
cout << "\nnew Array: " << c << endl;
c[n*m-1] = 3.0; // check that last elements are accessible
}
Edit:
It's also subject to the size_t limit.
Edit 2:
new[] throws bad_alloc exceptions when there is a problem, or even bad_array_new_length. You could try/catch these if you want. But if you prefer to get nullptr when there's not enough memory, you have to use (std::nothrow) as pointed out in the comments by Beat.
The best approach for your case, if you really need these huge number of floats, would be to go for vectors. As they are also subject to size_t limitation, but as you have in fact a 2D array, you could use vectors of vectors (if you have enough memory):
vector <vector<float>> v (n, vector<float>(m));

How many levels of pointers can we have?

How many pointers (*) are allowed in a single variable?
Let's consider the following example.
int a = 10;
int *p = &a;
Similarly we can have
int **q = &p;
int ***r = &q;
and so on.
For example,
int ****************zz;
The C standard specifies the lower limit:
5.2.4.1 Translation limits
276 The implementation shall be able to translate and execute at least one program that contains at least one instance of every one of the following limits: [...]
279 — 12 pointer, array, and function declarators (in any combinations) modifying an
arithmetic, structure, union, or void type in a declaration
The upper limit is implementation specific.
Actually, C programs commonly make use of infinite pointer indirection. One or two static levels are common. Triple indirection is rare. But infinite is very common.
Infinite pointer indirection is achieved with the help of a struct, of course, not with a direct declarator, which would be impossible. And a struct is needed so that you can include other data in this structure at the different levels where this can terminate.
struct list { struct list *next; ... };
now you can have list->next->next->next->...->next. This is really just multiple pointer indirections: *(*(..(*(*(*list).next).next).next...).next).next. And the .next is basically a noop when it's the first member of the structure, so we can imagine this as ***..***ptr.
There is really no limit on this because the links can be traversed with a loop rather than a giant expression like this, and moreover, the structure can easily be made circular.
Thus, in other words, linked lists may be the ultimate example of adding another level of indirection to solve a problem, since you're doing it dynamically with every push operation. :)
Theoretically:
You can have as many levels of indirections as you want.
Practically:
Of course, nothing that consumes memory can be indefinite, there will be limitations due to resources available on the host environment. So practically there is a maximum limit to what an implementation can support and the implementation shall document it appropriately. So in all such artifacts, the standard does not specify the maximum limit, but it does specify the lower limits.
Here's the reference:
C99 Standard 5.2.4.1 Translation limits:
— 12 pointer, array, and function declarators (in any combinations) modifying an
arithmetic, structure, union, or void type in a declaration.
This specifies the lower limit that every implementation must support. Note that in a footenote the standard further says:
18) Implementations should avoid imposing fixed translation limits whenever possible.
As people have said, no limit "in theory". However, out of interest I ran this with g++ 4.1.2, and it worked with size up to 20,000. Compile was pretty slow though, so I didn't try higher. So I'd guess g++ doesn't impose any limit either. (Try setting size = 10 and looking in ptr.cpp if it's not immediately obvious.)
g++ create.cpp -o create ; ./create > ptr.cpp ; g++ ptr.cpp -o ptr ; ./ptr
create.cpp
#include <iostream>
int main()
{
const int size = 200;
std::cout << "#include <iostream>\n\n";
std::cout << "int main()\n{\n";
std::cout << " int i0 = " << size << ";";
for (int i = 1; i < size; ++i)
{
std::cout << " int ";
for (int j = 0; j < i; ++j) std::cout << "*";
std::cout << " i" << i << " = &i" << i-1 << ";\n";
}
std::cout << " std::cout << ";
for (int i = 1; i < size; ++i) std::cout << "*";
std::cout << "i" << size-1 << " << \"\\n\";\n";
std::cout << " return 0;\n}\n";
return 0;
}
Sounds fun to check.
Visual Studio 2010 (on Windows 7), you can have 1011 levels before getting this error:
fatal error C1026: parser stack overflow, program too complex
gcc (Ubuntu), 100k+ * without a crash ! I guess the hardware is the limit here.
(tested with just a variable declaration)
There is no limit, check example at Pointers :: C Interview Questions and Answers.
The answer depends on what you mean by "levels of pointers." If you mean "How many levels of indirection can you have in a single declaration?" the answer is "At least 12."
int i = 0;
int *ip01 = & i;
int **ip02 = & ip01;
int ***ip03 = & ip02;
int ****ip04 = & ip03;
int *****ip05 = & ip04;
int ******ip06 = & ip05;
int *******ip07 = & ip06;
int ********ip08 = & ip07;
int *********ip09 = & ip08;
int **********ip10 = & ip09;
int ***********ip11 = & ip10;
int ************ip12 = & ip11;
************ip12 = 1; /* i = 1 */
If you mean "How many levels of pointer can you use before the program gets hard to read," that's a matter of taste, but there is a limit. Having two levels of indirection (a pointer to a pointer to something) is common. Any more than that gets a bit harder to think about easily; don't do it unless the alternative would be worse.
If you mean "How many levels of pointer indirection can you have at runtime," there's no limit. This point is particularly important for circular lists, in which each node points to the next. Your program can follow the pointers forever.
It's actually even funnier with pointer to functions.
#include <cstdio>
typedef void (*FuncType)();
static void Print() { std::printf("%s", "Hello, World!\n"); }
int main() {
FuncType const ft = &Print;
ft();
(*ft)();
(**ft)();
/* ... */
}
As illustrated here this gives:
Hello, World!
Hello, World!
Hello, World!
And it does not involve any runtime overhead, so you can probably stack them as much as you want... until your compiler chokes on the file.
There is no limit. A pointer is a chunk of memory whose contents are an address.
As you said
int a = 10;
int *p = &a;
A pointer to a pointer is also a variable which contains an address of another pointer.
int **q = &p;
Here q is pointer to pointer holding the address of p which is already holding the address of a.
There is nothing particularly special about a pointer to a pointer. So there is no limit on chain of poniters which are holding the address of another pointer.
ie.
int **************************************************************************z;
is allowed.
Every C++ developer should have heard of the (in)famous Three star programmer.
And there really seems to be some magic "pointer barrier" that has to be camouflaged.
Quote from C2:
Three Star Programmer
A rating system for C-programmers. The more indirect your pointers are (i.e. the more "*" before your variables), the higher your reputation will be. No-star C-programmers are virtually non-existent, as virtually all non-trivial programs require use of pointers. Most are one-star programmers. In the old times (well, I'm young, so these look like old times to me at least), one would occasionally find a piece of code done by a three-star programmer and shiver with awe.
Some people even claimed they'd seen three-star code with function pointers involved, on more than one level of indirection. Sounded as real as UFOs to me.
Note that there are two possible questions here: how many levels of pointer indirection we can achieve in a C type, and how many levels of pointer indirection we can stuff into a single declarator.
The C standard allows a maximum to be imposed on the former (and gives a minimum value for that). But that can be circumvented via multiple typedef declarations:
typedef int *type0;
typedef type0 *type1;
typedef type1 *type2; /* etc */
So ultimately, this is an implementation issue connected to the idea of how big/complex can a C program be made before it is rejected, which is very compiler specific.
I'd like to point out that producing a type with an arbitrary number of *'s is something that can happen with template metaprogramming. I forget what I was doing exactly, but it was suggested that I could produce new distinct types that have some kind of meta maneuvering between them by using recursive T* types.
Template Metaprogramming is a slow descent into madness, so it is not necessary to make excuses when generating a type with several thousand level of indirection. It's just a handy way to map peano integers, for example, onto template expansion as a functional language.
Rule 17.5 of the 2004 MISRA C standard prohibits more than 2 levels of pointer indirection.
There isn't such a thing like real limit but limit exists. All pointers are variables that are usually storing in stack not heap. Stack is usually small (it is possible to change its size during some linking). So lets say you have 4MB stack, what is quite normal size. And lets say we have pointer which is 4 bytes size (pointer sizes are not the same depending on architecture, target and compiler settings).
In this case 4 MB / 4 b = 1024 so possible maximum number would be 1048576, but we shouldn't ignore the fact that some other stuff is in stack.
However some compilers may have maximum number of pointer chain, but the limit is stack size. So if you increase stack size during linking with infinity and have machine with infinity memory which runs OS which handles that memory so you will have unlimited pointer chain.
If you use int *ptr = new int; and put your pointer into heap, that is not so usual way limit would be heap size, not stack.
EDIT Just realize that infinity / 2 = infinity. If machine has more memory so the pointer size increases. So if memory is infinity and size of pointer is infinity, so it is bad news... :)
It depends on the place where you store pointers. If they are in stack you have quite low limit. If you store it in heap, you limit is much much much higher.
Look at this program:
#include <iostream>
const int CBlockSize = 1048576;
int main()
{
int number = 0;
int** ptr = new int*[CBlockSize];
ptr[0] = &number;
for (int i = 1; i < CBlockSize; ++i)
ptr[i] = reinterpret_cast<int *> (&ptr[i - 1]);
for (int i = CBlockSize-1; i >= 0; --i)
std::cout << i << " " << (int)ptr[i] << "->" << *ptr[i] << std::endl;
return 0;
}
It creates 1M pointers and at the shows what point to what it is easy to notice what the chain goes to the first variable number.
BTW. It uses 92K of RAM so just imagine how deep you can go.