Allocating memory and reinterpreting pointer using new in C++ - c++

I want to allocate memory for n T objects by allocating n * sizeof(T) bytes and get a pointer using new. What's wrong in the following code?
template <class T>
void foo(size_t n, const T& value)
{
T* buffer = reinterpret_cast<T*>(new char[n * sizeof(T)]);
for (int i = 0; i < n; i++) {
buffer[i] = value;
std::cout << buffer[i] << std::endl;
}
std::cout << "success" << std::endl;
}
If i do foo<int>(n, int());, but if I call foo<std::string>(n, std::string()); i get segmentation fault.

You need to create an object in the memory, not just reinterpret the uninitialised bytes as an object. For int, you'll get away with it, since assignment will just overwrite whatever's there. std::string will (probably) contain an invalid pointer and size, and will think that these refer to data that it's supposed to delete or replace with the assigned value; hence the crash.
To create an object in pre-allocated memory, use placement-new instead of assignment:
new(&buffer[i]) T(value);
When you've finished with an object, you'll have to call its destructor yourself before deallocating the memory:
buffer[i].~T();
You could avoid this error-prone dance with std::vector<T> buffer(n, value); which does all this behind the scenes without troubling you about it.

Related

C++ placement new, Invalid read and InvalidInvalid free() / delete / delete[] / realloc()

I'm experimenting the usage of placement new to try to understand how it works.
Executing the code below:
#include <iostream>
#define SHOW(x) std::cout << #x ": " << x << '\n'
template<typename T>
static T *my_realloc(T *ptr, size_t count) {
return (T *) realloc((void *) ptr, count * sizeof(T));
}
template<typename T>
static void my_free(T *ptr) {
free((T *) ptr);
}
int main() {
constexpr int count = 40;
int cap = 0;
int size = 0;
std::string *strs = nullptr;
auto tmp_str = std::string();
for(int i = 0; i < count; i++) {
tmp_str = std::to_string(i);
if(size == cap) {
if(cap == 0)
cap = 1;
else
cap *= 2;
strs = my_realloc(strs, cap);
}
new (&strs[size++]) std::string(std::move(tmp_str));
}
for(int i = 0; i < size; i++)
SHOW(strs[i]);
std::destroy_n(strs, size);
my_free(strs);
return 0;
}
I get the errors:
Invalid read of size 1
Invalid free() / delete / delete[] / realloc()
Removing the line
std::destroy_n(strs, size);
The error of invalid free is solved, but somehow all memory of the program is freed and no leaks are generated. But i can't find how the std::string destructor is called in the program.
If you want to store non-trivial types (such as std::string), then realloc simply cannot be used. You will find that standard library containers like e.g. std::vector will also not use it.
realloc may either extend the current allocation, without moving it in memory, or it might internally make a new allocation in separate memory and copy the contents of the old allocation to the new one. This step is performed as if by std::memcpy. The problem here is that std::memcpy will only work to actually create new objects implicitly in the new allocation and copy the values correctly if the type is trivially-copyable and if it and all of its subobjects are implicit-lifetime types. This definitively doesn't apply to std::string or any other type that manages some (memory) resource.
You are also forgetting to check the return value of realloc. If allocation failed, it may return a null pointer, which you will then use regardless, causing a null pointer dereference, as well as a memory leak of the old allocation.
Instead of using realloc you should make a new allocation for the new size, then placement-new copies of the objects already in the old allocation into the new one and then destroy the objects in the old allocation and free it.
If you want to guarantee that there won't be memory leaks when exceptions are thrown things become somewhat complicated. I suggest you look at the std::vector implementation of one of the standard library implementations if you want to figure out the details.
strs = my_realloc(strs, cap);
strs is a pointer to a std::string, and this will result in the contents of the pointer to be realloc()ed.
This is undefined behavior. C++ objects cannot be malloced, realloced, or freeed. Using a wrapper function, or placement new, at some point along the way, does not change that.
Everything from this point on is undefined behavior, and the resulting consequences are of no importance.

Why my destructor shows that pointer being freed was not allocated c++

I want to implement 2 array addition, but when a destructor to the class SList
void operator+(SList list2) {
int totalLen = this->len + list2.len;
char** temp = new char* [totalLen];
for(int i = 0; i < len; i++) {
temp[i] = this->list[i];
}
for(int i = len, j = 0; i < totalLen; i++, j++) {
temp[i] = list2.get(j);
}
delete[] this->list;
this->list = temp;
this->len = totalLen;
cout << len << endl << endl;
}
Here are the get method that just return the dynamic array of char:
char* get(int i) {
if (i >= len) {
return "";
} else {
return list[i];
}
}
here are my class SList private variables:
private:
char** list;
int len;
char* generateString(){
char* str;
int n = rand() % 20 + 1;
str = new char[n + 1];
for(int i = 0; i < n; i++) {
str[i] = 'a' + rand()%26;
}
str[n] = '\0';
return str;
};
~SList() {
delete[] list;
}
It always shows malloc error on the destructor.
malloc: *** error for object 0x105007410: pointer being freed was not allocated
malloc: *** set a breakpoint in malloc_error_break to debug
Please help! I have carefully checked my delete method on the dynamic allocated array, but it always shows this error.
I have tried to check other delete from the other function, but none of them make the same malloc error. I have tried to commented the destructor method and everything work fine. But i really need to have destructor method here. I hope someone with more expertise on c++ can help me fix this malloc error and gave an explanation on which part i made a mistake.
Regardless what are other details of implementation, the destructor is not correct while you're using a data structure known as a "ragged array", i.e. list is a pointer to an array of pointers. delete[] would free the pointer array, but not char arrays pointed by its elements. You have to do something like this:
~SList() {
if(!list) return; // if we cannot guarantee that list isn't
// nullptr we have to check it,
// or result of list[i] would be undefined.
for(int i = 0; i < len; i++)
delete[] list[i];
delete[] list;
}
and you have to make sure that any of those pointers is either initialized by new expression or is equal nullptr.. It doesn't happen on its own. You have to make sure during construction and all operations. You didn't show any. Look for faults there.
The method get() is a disaster waiting to happen and is ill-formed, i.e. it doesn't follow C++ rules. The string literal "" returns const char*, always the same one and the statement return ""; is incorrect - some compilers only warn about it though. It cannot be deallocated by delete.
char* get(int i) {
if (i >= len) {
return nullptr; // "" - is not safe
} else {
return list[i];
}
}
Deleting a nullptr is a safe no-op. Deleting something that was't returned by new is a disaster.
The addition operator is taking list2 by value, which means that proper copy operations have to be implemented. You didn't show them either. Default implementation would just copy a pointer and destruction of local copy would deallocate memory used by original via ~SList() above. The operator have to return resulting object and should not modify one pointed by this. You had implemented an operator+=. The way you did it, it would work as
a+b; // a now contains result of concatenation.
It's simply weird to use. Proper operator would be
SList operator+(SList& list2);
In general, an object that deals with ownership of some resource, dynamic memory in our case, have to implement certain set of special member functions:
~SList();
SList(const SList& other);
SList(SList&& other); // move copy, source is a temporal.
SList& operator=(const SList& other);
SList& operator=(SList&& other); // move assignment
If that is done right, you can safely do the c = a + b; assignment.
Note that if you pass argument by reference you have to take in account that arguments of assigning operators aren't referencing the object pointed by this and act accordingly if they are. Otherwise you would destroy it and loose original data. On other hand copying argument is excessive and user-unfriendly due to increased cost and memory footprint. Concatenation of n-element and m-element array is expected to have memory footprint of n+m elements , not n+2*m.

Heap corruption when using make_shared

I have a class with private member variable
shared_ptr<short> m_p_data;
I get heap corruption when I use this constructor:
Volume2D(const int dimX, const int dimY) :m_dimX{ dimX }, m_dimY{ dimY }, m_p_data{ make_shared<short>(dimX*dimY) } {
}
but there is no heap corruption if I do this instead:
Volume2D(const int dimX, const int dimY) :m_dimX(dimX), m_dimY(dimY) {
m_p_data.reset(new short[dimX*dimY]);
}
To be more specific, here is the code that corrupts the heap:
Volume2D vol(10, 1);
for (auto i = 0; i < 10; ++i) {
vol(i, 0) = i;
cout << "value = " << vol(i, 0) << endl;
}
return 0;
Both versions of your code are problematic.
The first version,
make_shared<short>(dimX*dimY)
creates a single heap-allocated short with the value dimX*dimY. It is apparent from the rest of your question, that your code later treats this logically as an array of dimension dimX*dimY, which is exactly what's causing the heap corruption (you only allocated a single short, but you're treating it like many).
The second version has the opposite problem. You're allocating dimX*dimY shorts, but, as far as your shared_ptr, it doesn't know that. So it doesn't have your heap corruption, but the shared_ptr destructor calls delete, not delete[] (even though you allocated with new[], not new).
For this case, its' unclear why you need a shared_ptr to begin with. Why not use std::vector<short>, or std::vector<std::vector<short>>?

Portable emulation of flexible array member in C++?

I'm writing a skip list.
What I have:
template<typename T>
struct SkipListNode
{
T data;
SkipListNode* next[32];
};
The problem with this code is that it wastes space - it requires all nodes to contain 32 pointers. Especially considering that in typical list, half of the nodes will only need one pointer.
The C language has a neat feature called flexible array member that could solve that problem. Had it existed in C++ (even for trivial classes), I could write code like this:
template<typename T>
struct SkipListNode
{
alignas(T) char buffer[sizeof(T)];
SkipListNode* next[];
};
and then manually create nodes with a factory function and destroying them when deleting elements.
Which brings the question - how can I emulate such functionality portably, without undefined behaviour in C++?
I considered mallocing the buffer and then manipulating the offsets appropriately by hand - but it's too easy to violate the alignment requirements - if you malloc(sizeof(char) + sizeof(void*)*5), the pointers are unaligned. Also, I'm not even sure if such hand-created buffers are portable to C++.
Note that I don't require the exact syntax, or even ease of use - this is a node class, internal to the skip list class, which won't be a part of the interface at all.
This is the implementation I wrote, based on R. Martinho Fernandes's idea - it constructs a buffer that happens to have a correct size and alignment in specific places (the AlignmentExtractor is used extract the offset of the pointer array, which ensures that the pointers in the buffer have correct alignment). Then, placement-new is used to construct the type in the buffer.
T isn't used directly in AlignmentExtractor because offsetof requires standard layout type.
#include <cstdlib>
#include <cstddef>
#include <utility>
template<typename T>
struct ErasedNodePointer
{
void* ptr;
};
void* allocate(std::size_t size)
{
return ::operator new(size);
}
void deallocate(void* ptr)
{
return ::operator delete(ptr);
}
template<typename T>
struct AlignmentExtractor
{
static_assert(alignof(T) <= alignof(std::max_align_t), "extended alignment types not supported");
alignas(T) char data[sizeof(T)];
ErasedNodePointer<T> next[1];
};
template<typename T>
T& get_data(ErasedNodePointer<T> node)
{
return *reinterpret_cast<T*>(node.ptr);
}
template<typename T>
void destroy_node(ErasedNodePointer<T> node)
{
get_data(node).~T();
deallocate(node.ptr);
}
template<typename T>
ErasedNodePointer<T>& get_pointer(ErasedNodePointer<T> node, int pos)
{
auto next = reinterpret_cast<ErasedNodePointer<T>*>(reinterpret_cast<char*>(node.ptr) + offsetof(AlignmentExtractor<T>, next));
next += pos;
return *next;
}
template<typename T, typename... Args>
ErasedNodePointer<T> create_node(std::size_t height, Args&& ...args)
{
ErasedNodePointer<T> p = { nullptr };
try
{
p.ptr = allocate(sizeof(AlignmentExtractor<T>) + sizeof(ErasedNodePointer<T>)*(height-1));
::new (p.ptr) T(std::forward<T>(args)...);
for(std::size_t i = 0; i < height; ++i)
get_pointer(p, i).ptr = nullptr;
return p;
}
catch(...)
{
deallocate(p.ptr);
throw;
}
}
#include <iostream>
#include <string>
int main()
{
auto p = create_node<std::string>(5, "Hello world");
auto q = create_node<std::string>(2, "A");
auto r = create_node<std::string>(2, "B");
auto s = create_node<std::string>(1, "C");
get_pointer(p, 0) = q;
get_pointer(p, 1) = r;
get_pointer(r, 0) = s;
std::cout << get_data(p) << "\n";
std::cout << get_data(get_pointer(p, 0)) << "\n";
std::cout << get_data(get_pointer(p, 1)) << "\n";
std::cout << get_data(get_pointer(get_pointer(p, 1), 0)) << "\n";
destroy_node(s);
destroy_node(r);
destroy_node(q);
destroy_node(p);
}
Output:
Hello world
A
B
C
Longer explanation:
The point of this code is to create a node dynamically, without using types directly (type erasure). This node stores an object, and N pointers, with N variable at runtime.
You can use any memory as if it had a specific type, provided that:
size is correct
alignment is correct
(only non-triviably constructible types) you manually call the constructor before using
(only non-triviably destructible types) you manually call the destructor after using
In fact, you rely on this every time you call malloc:
// 1. Allocating a block
int* p = (int*)malloc(5 * sizeof *p);
p[2] = 42;
free(p);
Here, we treat the chunk of memory returned by malloc as if it was an array of ints. This must work because of these guarantees:
malloc returns a pointer guaranteed to be properly aligned for any object type.
If your pointer p points to aligned memory, (int*)((char*)p + sizeof(int)) (or p + 1, which is equivalent) also does.
The dynamically created node must have enough size to contain N ErasedNodePointers (which are used as handles here) and one object of size T. This is satisfied by allocating enough memory in create_node function - it will allocate sizeof(T) + sizeof(ErasedNodePointer<T>)*N bytes or more, but not less.
That was the first step. The second is now we extract the required position relative to the beginning of a block. That's where AlignmentExtractor<T> comes in.
AlignmentExtractor<T> is a dummy struct I use to ensure correct alignment:
// 2. Finding position
AlignmentExtractor<T>* p = (AlignmentExtractor<T>*)malloc(sizeof *p);
p->next[0].ptr = nullptr;
// or
void* q = (char*)p + offsetof(AlignmentExtractor<T>, next);
(ErasedTypePointer<T>*)q->ptr = nullptr;
It doesn't matter how I got the position of the pointer, as long as I obey the rules of pointer arithmetic.
The assumptions here are:
I can cast any pointer to void* and back.
I can cast any pointer to char* and back.
I can operate on a struct as if it was a char array of size equal to the size of the struct.
I can use pointer arithmetic to point at any element of an array.
These all are guaranteed by C++ standard.
Now, after I have allocated the block of enough size, I calculate the offset with offsetof(AlignmentExtractor<T>, next) and add it to the pointer pointing to the block. We "pretend" (the same way the code "1. Allocating a block" pretends it has an array of ints) the result pointer points to beginning of the array. This pointer is aligned correctly, because otherwise the code "2. Finding position" couldn't access the next array due to misaligned access.
If you have a struct of standard layout type, the pointer to the struct has the same address as the first member of the struct. AlignmentExtractor<T> is standard layout.
That's not all though - requirements 1. and 2. are satisfied, but we need to satisfy requirements 3. and 4. - the data in the node doesn't have to be trivially constructible or destructible. That's why we use placement-new to construct the data - the create_node uses variadic templates and perfect forwarding to forward arguments to the constructor. And the data is destroyed in the destroy_node function by calling the destructor.

Returning an array pointer from a function in C/C++ without static integer

I'm going to write a piece of code (Function) that returns a pointer to an array.
but I don't know how to do that.
The code I wrote is :
int* prime_factor(int temp){
int ctr;
int *ret;
int i = 0;
while (temp != 1){
ctr = 2;
if (temp%ctr != 0){
ctr++;
}
else {
*(ret + i) = ctr;
temp /= ctr;
}
}
return ret;
}
I guess that there's a need to such the thing :
else {
ret = new int[1];
*(ret +i) = ctr;
temp /= ctr;
}
But as you know , implementation of this stuff needs to be deleted the memory that you have allocated , so we have to delete the memory outside of the function , so it going to be nonstandard function.
Indeed, i want to calculate the Prime factors of a number then return them out.
Any idea to do that ? I don't know what should I do to gain the goal.
thank you so much.
I see your question has also the tag C++ so, you could use C++. I don't really know what you mean with without static integer ....
Use vector.
#include <vector>
vector<int> prime_factor(int number)
{
int ctr = 2;
vector<int> factors;
while (number != 1)
{
if (number % ctr != 0)
ctr++;
else
{
factors.push_back(ctr);
number /= ctr;
}
}
return factors;
}
As you will be using the vector with integers it knows how to destroy ("delete") it self.
Example:
int main()
{
for (auto &x : prime_factor(20)) // C++11
{
cout << x << endl;
}
}
Output:
2
2
5
Yes, putting burden of deleting the array on user is not preferable. Here you would be better off using vector instead of plain array.
You can also pass array as an argument(created in the caller so that it would be more intuitive to use delete on that array) to this function.
The line *(ret + i) = ctr; will create a memory violation right away, since your ret pointer has no allocated memory pointing to. You nee do preallocate a memory for it, either statically (array declaration) in the code CALLING this function, and passing it to the function as a parameter, or dynamically (using malloc or similar) and then freeing it in some point. Dynamic allocation can be done either in the function itself or in the calling code. But again, free the memory afterwards.
int *ret;
In your case ret doesn't point to any memory location.You are trying to reference some unallocated memory location which might cause segmentation fault.
Just to show how to return a pointer and free it below is the example:
int *some()
{
int *ret = malloc(sizeof(int));
*ret = 10;
return ret;
}
int main()
{
int *p = some();
printf("%d\n",*p);
free(p);
}
"But as you know , implementation of this stuff needs to be deleted the memory that you have allocated , so we have to delete the memory outside of the function , so it going to be nonstandard function."
To avoid that dilemma c++ has introduced Dynamic memory management support.
Instead of using raw pointers like int* use one appropriate of
std::unique_ptr<int> (to transfer ownership)
std::shared_ptr<int> (to share ownership)
std::weak_ptr<int> (to share ownership, but not count as reference)
std::auto_ptr<int> (to transfer ownership "the old way")
Besides that, it looks like using a std::vector<int> would be much more appropriate, than using a simple int*. The std::vector<int> class also is purposed to release you from getting the dynamic memory management right on your own.