Issue with pointers to memory allocation - c++

Considering the following code block:
Byte* b = (Byte*) var.rawBuffer();
b += sizeof (Byte) * 9;
WhateverType* aptr = (WhateverType*) b;
WhateverType* anotherptr = aptr;
for (int i = 0; i < N; i++) {
assert(*anotherptr == aptr[i]);
anotherptr += sizeof (WhateverType);
}
Why do the assertion fail, sometimes? Is not scanning allocated memory using the [] operator with an index on the starting memory address equivalent to increment the pointer address by the size of the data type I am trying to read?

The problem is this line:
anotherptr += sizeof (WhateverType);
anotherptr is a WhateverType* pointer, not a Byte* pointer. When you perform arithmetic on a typed pointer, the total byte count is an even multiple of the type that the pointer is declared as.
So, in the line above, you are not telling the compiler to increment the pointer by just sizeof (WhateverType) number of bytes only, like you are expecting. You are actually telling it to increment the pointer by sizeof(WhateverType) number of elements, or in other words, by sizeof(WhateverType) * sizeof(WhateverType) number of bytes.
T *pointer = ...;
pointer += N;
Is effectively equivalent to the following:
pointer = reinterpret_cast<T*>(reinterpret_cast<byte*>(pointer) + (sizeof(T) * N));
Even the statement aptr[i] works the same way, as the expression pointer[N] is just syntax sugar for *(pointer + N).
For what you are attempting, you need to increment your anotherptr pointer by N=1 element, not by N=sizeof(WhateverType) number of elements. So, use this instead:
anotherptr += 1;
Or simpler:
anotherptr++; // or: ++anotherptr;

Related

how do I solve this C++ access violation problem?

I'm getting an error in the following code. Visual Studio throws an access violation error when writing to _buf. How can I fix this?
The Sendn function is a socket sending function. It's not the problem, you can ignore it.
It looks like _buf points at 0x00000000
The error message I'm seeing is
0xC0000005: 0x00000000 : access violation
void ?????::?????(int number, string title)
{
int titlesize = sizeof(title);
int bufsize = 4 + 4 + 4 + titlesize;
char *_buf = new char[bufsize];
_buf = { 0 };
// char _buf[bufsize] = { 0 }; (수정 내용)
int commands = 3;
int index = 0;
memcpy(_buf, &commands, sizeof(int));
index += sizeof(int);
memcpy(_buf + index, &number, sizeof(int));
index += sizeof(int);
memcpy(_buf + index, &titlesize, sizeof(int));
index += sizeof(int);
for (int i = 0; i < titlesize; i++)
{
memcpy(_buf + index, &title[i], sizeof(char));
index += sizeof(char);
}
Sendn(_buf, bufsize);
delete[] _buf;
return;
}
char *_buf = new char[bufsize];
_buf = { 0 };
This does not zero-fill the dynamically-allocated array pointed to by _buf. It sets the pointer _buf to be a null pointer. Since _buf is a null pointer, later attempts to dereference it lead to undefined behavior.
There's no need to zero-fill the array pointed to by _buf in this case, so you can simply remove the _buf = { 0 }; line.
Once you've fixed that problem, you also aren't allocating the right amount of memory. sizeof(title) will not give you the number of characters that title holds. It just gives you the static size of a std::string object, which is usually only a pointer and two integers. Use title.size() instead.
You're trying to copy the content of title together with 3 other integer numbers into _buf right? The problem is that sizeof(title) is not the length of the string stored in title. In order to get the length of title, you need to call the member function length on type std::string like this:
auto titlesize = title.length();
The sizeof operator only gives you the size of your std::string object on stack (in comparison, the actual string is stored on heap) and sizeof expressions are always constant expressions. On my computer, sizeof(std::string) is 24 regardless of what the actual string is.

c++ : An array of the pointer float type with dynamic size

Is this Correct?
Will stereoBuffer be an array of the pointer float type with size mixQty (i.e. 2);
// C++ in Header File
float **stereoBuffer;
// in cpp file inside a function of init
mixQty = 2; // this will be passed in function
stereoBuffer = new float*[mixQty];
for (int i = 0; i < mixQty; ++i) {
stereoBuffer[i] = (float *)malloc(samplerate * 2 * sizeof(float) + 32768);
}
Help and Detail answer will be rewarded.
Is this Correct?
No. Mixing new and malloc() is not a good idea.
If you must use dynamic memory allocation, then read this: How do I declare a 2d array in C++ using new?
Otherwise, use an std::vector.
Will stereoBuffer be an array of the pointer float type
It will be (a pointer to the first element of) an array of type pointer-to-float.
Each element of this array will be a pointer to the first element of an array of float.
As gsamaras notes, mixing new and malloc like this is terrible practice. It's needlessly hard to correctly deallocate and there's no error checking. You could at least use std::vector<std::unique_ptr<float[]>> and let it take care of deallocation correctly for you.
using StereoBuffer = std::vector<std::unique_ptr<float[]>>;
StereoBuffer allocateStereoBuffer(size_t mixQty, size_t samplerate)
{
StereoBuffer buf(mixQty);
for (size_t i = 0; i < mixQty; ++i) {
buf[i] = make_unique<float[]>(samplerate * 2 * 32768); // ?
}
return buf;
}

C++ Struct to Byte* throwing error

I have attached my code below. I do not see what I am doing wrong. I have a struct that I am trying to serialize into a byte array. I have wrote some some simple code to test it. It all appears to work during runtime when I print out the values of objects, but once I hit return 0 it throws the error:
Run-Time Check Failure #2 - Stack around the variable 'command' was corrupted.
I do not see the issue. I appreciate all help.
namespace CommIO
{
enum Direction {READ, WRITE};
struct CommCommand
{
int command;
Direction dir;
int rwSize;
BYTE* wData;
CommCommand(BYTE* bytes)
{
int offset = 0;
int intsize = sizeof(int);
command = 0;
dir = READ;
rwSize = 0;
memcpy(&command, bytes + offset, intsize);
offset += intsize;
memcpy(&dir, bytes + offset, intsize);
offset += intsize;
memcpy(&rwSize, bytes + offset, intsize);
offset += intsize;
wData = new BYTE[rwSize];
if (dir == WRITE)
{
memcpy(&wData, bytes + offset, rwSize);
}
}
CommCommand() {}
}
int main()
{
CommIO::CommCommand command;
command.command = 0x6AEA6BEB;
command.dir = CommIO::WRITE;
command.rwSize = 128;
command.wData = new BYTE[command.rwSize];
for (int i = 0; i < command.rwSize; i++)
{
command.wData[i] = i;
}
command.print();
CommIO::CommCommand command2(reinterpret_cast<BYTE*>(&command));
command2.print();
cin.get();
return 0;
}
The following points mentioned in comments are most likely the causes of your problem.
You seem to be assuming that the size of Direction is the same as the size of an int. That may indeed be the case, but C++ does not guarantee it.
You also seem to be assuming that the members of CommIO::CommCommand will be laid out in memory without any padding between, which again may happen to be the case, but is not guaranteed.
There are couple of ways to fix the that.
Make sure that you fill up the BYTE array in the calling function with matching objects, or
Simply cast the BYTE* to CommCommand* and access the members directly.
For (1), you can use:
int command = 0x6AEA6BEB;
int dir = CommIO::WRITE;
int rwSize = 128;
totatlSize = rwSize + 3*sizeof(int);
BYTE* data = new BYTE[totalSize];
int offset = 0;
memcpy(data + offset, &comand, sizeof(int));
offset += sizeof(int);
memcpy(data + offset, &dir, sizeof(int));
offset += sizeof(int);
memcpy(data + offset, &rwSize, sizeof(int));
offset += sizeof(int);
for (int i = 0; i < rwSize; i++)
{
data[i + offset] = i;
}
CommIO::CommCommand command2(data);
For (2), you can use:
CommCommand(BYTE* bytes)
{
CommCommand* in = reinterpret_cast<CommCommand*>(bytes);
command = in->command;
dir = in->dir;
rwSize = in->size;
wData = new BYTE[rwSize];
if (dir == WRITE)
{
memcpy(wData, in->wData, rwSize);
}
}
The other error is that you are using
memcpy(&wData, bytes + offset, rwSize);
That is incorrect since you are treating the address of the variable as though it can hold the data. It cannot.
You need to use:
memcpy(wData, bytes + offset, rwSize);
The memory for your struct is laid out without padding, this can be rectified by adding the macro #pragma pack(1) at the start of the struct and #pragma pop() at the end of the struct - check its syntax though.
For your struct to byte conversion, I would use something simple as:
template<typename T, typename IteratorForBytes>
void ConvertToBytes(const T& t, IteratorForBytes bytes, std::size_t pos = 0)
{
std::advance(bytes, pos);
const std::size_t length = sizeof(t);
const uint8_t* temp = reinterpret_cast<const uint8_t*>(&t);
for (std::size_t i = 0; i < length; ++i)
{
(*bytes) = (*temp);
++temp;
++bytes;
}
}
Where T is the is the struct in your case your Command struct and bytes would be the array.
CommIO::CommCommand command;
command.wData = new BYTE[command.rwSize];
ConvertToBytes(command, command.wData);
The resulting array would contain the expected bytes You could specify the offset as well as an extra parameter if you want to start filling your byte array from a particular location
The main problem is here:
memcpy(&wData, bytes + offset, rwSize);
Member wData is a BYTE *, and you seem to mean to copy bytes into the space to which it points. Instead, you are copying data into the memory where the pointer value itself is stored. Therefore, if you copy more bytes than the size of the pointer then you will overrun its bounds and produce undefined behavior. In any case, you are trashing the original pointer value. You probably want this, instead:
memcpy(wData, bytes + offset, rwSize);
Additionally, although the rest of the deserialization code may be right for your actual serialization format, it is not safe to assume that it is right for the byte sequence you present to it in your test program via
CommIO::CommCommand command2(reinterpret_cast<BYTE*>(&command));
As detailed in comments, you are making assumptions about the layout in memory of a CommIO::CommCommand that C++ does not guarantee will hold.
At
memcpy(&wData, bytes + offset, rwSize);
you copy from the location of the wData pointer and to the location of the wData pointer of the new CommCommand. But you want to copy from and to the location that the pointer points to. You need to dereference. You corrupt the heap, because you have only sizeof(BYTE*) space (plus some extra, because heap blocks cannot be arbitrarily small), but you copy rwSize bytes, which is 128 bytes. What you probably meant to write is:
memcpy(wData, *(BYTE*)(bytes + offset), rwSize);
which would take use the pointer stored at bytes + offset, rather than the value of bytes + offset itself.
You also assume that your struct is tightly packed. However, C++ does not guarantee that. Is there a reason why you do not override the default copy constructor rather than write this function?

C-style 2D-dynamic array with need to perform only one free() operation

I want to build 2D-array without need to perform many free() operations.
#include <iostream>
#define un unsigned
#define ln long
un ln ** array_builder(un ln rows, un ln cols)
{
register const un ln row_memory = cols * sizeof(un ln);
auto array = (un ln **) malloc( rows * ( sizeof(un ln *) + row_memory ) );
// First line: The bytes of memory required to store a single row in the array
// Second line: We want to store all the pointers in the single array
auto pointer = (void *) array[0]; // sizeof(void *) == 1. It is convenient for our purposes
pointer += rows * sizeof(un ln *); /* Thus we skip the first pointers in the array (their amount equals 'rows').
This space is considered to store pointers of array[row] type */
for (un ln int i = 0; i < rows; i++)
{
array[i] = (un ln *) pointer; // We write pointers to each row in the array[row]
pointer += row_memory;
}
return array;
// We've built 2D-array. Now we can access to the elements of this array by convenient way as array[row][col]
// Don't forget to free(array) after use
}
But this program works incorrect. For example, when I try to change some value by array[row][col]=some_value it makes program crash in different places every time.
In C++, one does not use malloc and free nor the equivalent new and delete. One would use proper RAII, that is, no manual freeing resources.
For a 2 dimensional array, one would use a single field like this:
std::vector<int> data;
data.resize(width * height);
//in case you know the amount of data at compile time use a static sized field
std::array<int, width * heigth> data;
//access a single cell
int cell = data[y * width + x];
//or obtain a pointer to a row of cells
int *rowptr = &data[y * width];
int cellinrow = rowptr[x];
This is both more space and time efficient than allocating multiple rows.
In C you would equivalently allocate a single block of ints with malloc or use a static sized int[width * height] array;
Note that you should never mix C and C++ nor use the register keyword nor lazy #defines
You cannot. The compiler needs to know what type to return and this requires the size of the internal array. Plus you can't return arrays anyway.
What you could do is make a class that does it for you. You could call it say, vector, or something. Make it responsible for allocating and deallocating a dynamic array of some type...then put one inside of another like so:
vector<vector<unsigned long>> {rows, vector<unsigned long>{cols,0}};
You might be able to find someone has already written something like this if you peruse the Internet for C++ tutorials and references.
Algorithm for a fake 2D array unsigned long ** - which is a pointer to a pointer to unsigned long
The allocation needs to
1) enough memory for the array of pointers array.
2) maybe some padding for alignment of unsigned long
3) rows*cols memory of unsigned long
This can all be done with 1 allocation and so only 1 free() is needed.
Assign the array elements to point to the 3rd part of the allocation. Keep in mind alignment requirements.
Unclear why C++ code would want this.
OP's approach is similar, yet lacks the alignment considerations. This can crash code if a pointer is narrower than unsigned long or under other circumstances.
--
Some untested C++ like code in the manner of "C-style" using malloc().
typedef unsigned long data_t;
data_t **alloc_2Ddata(size_t rows, size_t cols) {
data_t **a;
size_t row_ptrs_size = sizeof *a * rows;
size_t data_size = sizeof **a * rows * cols;
size_t pad = (sizeof **a - row_ptrs_size % sizeof **a) % sizeof **a;
a = (data_t **) malloc(row_ptrs_size + pad + data_size);
if (a) {
data_t *data = (data_t*) (((char*) a) + row_ptrs_size + pad);
for (size_t r = 0; r < rows; r++) {
a[r] = data;
data += cols;
}
}
return a;
}

Realloc returning null?

I allocate some memory with malloc - about 128 bytes.
Later on, I call realloc with about 200 bytes, but it's returning null!
It returns a valid pointer if I do free, and then another malloc, however I would like to use realloc.
What could explain this behavior (I clearly am not running out of memory)? Is this valid behavior?
Code bits:
//class constructor
size = 0;
sizeAllocated = DEFAULT_BUFFER_SIZE; //64
data = (char*)malloc(sizeAllocated * sizeof(char)); //data is valid ptr now, I've checked it
data[0] = '\0';
//later on:
//append function
bool append(char** data, const char* str, size_t strLen) {
if((size + strLen) >= sizeAllocated) {
sizeAllocated += strLen + 1 + BUFFER_ALLOCATION_STEP;
char* temp = realloc(*data, sizeAllocated * sizeof(char));
if(temp)
*data = temp;
return( temp != NULL );
}
EDIT: fixed. I was overloading the << operator for my class, and had it return *this instead of void. Somehow this was screwing everything up! If anyone could explain why this happen, it would be nice!
Since the following comment was added to the question
data = (char*)realloc(data, (size_t)(sizeAllocated * sizeof(char)));
if I replace sizeAllocated with a
constant that is same value, it
reallocs correctly
Now we can figure out what happened. You replaced sizeAllocated with a constant that DID NOT have the same value. For debugging purposes, add a statement that will output the value of sizeAllocated and you will be surprised.