Exception thrown: write access violation. this was nullptr - c++

So I am trying to make a buffer class. This buffer class contains a huge buffer of size 384*4. The plan was for every UDP datagram received, size(384), the buffer class is called and return a pointer to where the datagram should be written.
And there will be another listener pointer to which RtAudio playback will memcpy from. [The listening part is not entirely relevant yet as I still have a problem writing into the buffer]
When I try to call server_->getPointer() (shown below), the "Exception thrown: write access violation. this was nullptr." is thrown. Please help me!! and tell me if there is anything else that I should provide.
Buffer.h
#pragma once
#ifndef BUFFER_H
#define BUFFER_H
class Buffer {
private:
int bufferSize = 192 * 2; // one frame takes 2 Byte [int16]
int nBuffers = 4;
int *buffer_ = nullptr;
int* writerPointer = nullptr;
int* listenerPointer = nullptr;
int writerCounter = 0;
int listenerCounter = 0;
int* tempW = nullptr;
int* tempL = nullptr;
public:
Buffer();
~Buffer();
int* getWriterPointer();
int* getlistenerPointer();
int * getPointer();
};
#endif // !BUFFER_H
Buffer.cpp
#include"Buffer.h"
#include <iostream>
Buffer::Buffer() {
buffer_ = reinterpret_cast<int*>(malloc(bufferSize*nBuffers));
memset(buffer_, (int)5, bufferSize*nBuffers);
std::cout << "new Buffer" << bufferSize * nBuffers << std::endl;
listenerPointer = buffer_;
writerPointer = buffer_;
std::cout << "HERE " << *buffer_ << std::endl;
std::cout << "new Buffer" << bufferSize * nBuffers << " pointer a " << listenerPointer << " pointer b " << writerPointer << std::endl;
}
Buffer::~Buffer() {
delete buffer_;
}
...
//For teting purposes
int* Buffer::getPointer(){
bufferSize = 192 * 2;
std::cout << "get pointer asdfasdf::" << writerCounter << std::endl;
std::cout << "pointer's position offset: " << writerCounter - 1 << std::endl;
if (writerCounter == nBuffers - 1) {
writerCounter = 0;
return writerPointer + (bufferSize*(nBuffers - 1));
}
else {
writerCounter += 1;
return writerPointer + (bufferSize*(writerCounter - 1));
}
}
main.cpp
#include <iostream>
#include "Buffer.h"
int main()
{
std::cout << "Hello World!\n";
Buffer *buffer_ = new Buffer();
buffer_->getPointer();
}

Look up "zero copying" for the protocol part.
The problem you have is that your pointer is actually a nullptr at the time you are trying to use it. You need to check the return from malloc:
Buffer::Buffer() :
buffer_(reinterpret_cast<int*>(malloc(bufferSize*nBuffers)))
{
if(buffer_ == nullptr) throw std::bad_alloc();
}
But, you should use new instead which would do this check and throw bad_alloc automatically if it fails:
Buffer::Buffer() :
buffer_(new int[bufferSize*nBuffers])
{
// no need to check here
}
For every malloc you need one free, and for every new you need one delete - and you should never mix them.
Also, malloc allocates bytes, but an int is usually 4 or 8 bytes so you'd need to multiply the number of ints you want to allocate space for with sizeof(int)*CHAR_BIT/8 to get the correct size.
Just forget about malloc and free and use new and delete in their place.
This is how you delete your array allocated with new int[...]:
Buffer::~Buffer() {
delete[] buffer_; // delete array
}
An even better option is to use a std::unique_ptr which will do the delete[] for you when it goes out of scope:
class Buffer {
private:
std::unique_ptr<int[]> buffer_;
public:
Buffer() :
buffer_(std::make_unique<int[]>(bufferSize * nBuffers))
{}
// ~Buffer() no need to implement a destructor unless you manually handle resources
};

Related

Why does loading a block of memory from a DLL only crash at the second call to memmove?

This is the class in question (only functions that pertain to this question) and everything it depends on (all written myself). It provides an interface to a DLL.
struct MemRegion {
const uint64_t address;
const uint64_t size;
};
enum Version {
VERSION_US,
VERSION_JP
};
const struct MemRegion SEGMENTS[2][2] = {
{{1302528, 2836576},
{14045184, 4897408}},
{{1294336, 2406112},
{13594624, 4897632}},
};
using Slot = array<vector<uint8_t>, 2>;
class Game {
private:
Version m_version;
HMODULE m_dll;
const MemRegion* m_regions;
public:
Game(Version version, cstr dll_path) {
m_version = version;
m_dll = LoadLibraryA(dll_path);
if (m_dll == NULL) {
unsigned int lastError = GetLastError();
cerr << "Last error is " << lastError << endl;
exit(-2);
}
// this is a custom macro which calls a function in the dll
call_void_fn(m_dll, "sm64_init");
m_regions = SEGMENTS[version];
}
~Game() {
FreeLibrary(m_dll);
}
void advance() {
call_void_fn(m_dll, "sm64_update");
}
Slot alloc_slot() {
Slot buffers = {
vector<uint8_t>(m_regions[0].size),
vector<uint8_t>(m_regions[1].size)
};
return buffers;
}
void save_slot(Slot& slot) {
for (int i = 0; i < 2; i++) {
const MemRegion& region = m_regions[i];
vector<uint8_t>& buffer = slot[i];
cerr << "before memmove for savestate" << endl;
memmove(buffer.data(), reinterpret_cast<void* const>(m_dll + region.address), region.size);
cerr << "after memmove for savestate" << endl;
}
}
};
When I call save_slot(), it should copy two blocks of memory to a couple of vector<uint8_t>s. This does not seem to be the case, though. The function finishes the first copy, but throws a segmentation fault at the second memcpy. Why does it only happen at the second copy, and how can I get around this sort of issue?
Edit 1: This is what GDB gives me when the program terminates:
Thread 1 received signal SIGSEGV, Segmentation fault.
0x00007ffac2164452 in msvcrt!memmove () from C:\Windows\System32\msvcrt.dll
Edit 2: I tried accessing the segments individually. It works, but for some reason, I can't access both segments in the same program.
I found out that HMODULE is equivalent to void*. Since you can't really use pointer arithmetic on void*s, you have to cast it to a uint8_t* or equivalent to properly get an offset.
Here's what that looks like in practice:
void save_state(Slot& slot) {
uint8_t* const _dll = (uint8_t*)((void*)m_dll);
for (int i = 0; i < 2; i++) {
MemRegion segment = m_regions[i];
std::vector<uint8_t>& buffer = slot[i];
memmove(&buffer[0], _dll + segment.address, segment.size);
}
}

Pointer being freed was not allocated even though it was allocated before

I have error that says error for object 0x7ffbaf002000: pointer being freed was not allocated. But I have printed out the memory address and it was indeed allocated before at 0x7ffbaf002000 in the function allocFlights(Flight**, int) inside the loop when flight[0] = (Flight*) malloc(sizeof(Flight) * 60). So I print out the memory address at std::cout << flight[0] << std::endl in function deAllocFlights(Flight**, int) to see if it's there and it is there at 0x7ffbaf002000 inside the loop
I don't understand why I have this problem. I'm still new at C++.
Here is the struct Flight:
typedef struct {
int flightNum;
char origin[20];
char destination[20];
Plane *plane;
}Flight;
void getAllFlights(Flight **flight) {
FILE *file = fopen("reservation.txt", "r");
int i = 0, totalFlights;
if(file == NULL)
{
perror("Error in opening file");
}
fscanf(file, "%d\n", &totalFlights);
*flight = (Flight*) malloc(sizeof(Flight*) * totalFlights);
allocFlights(flight, totalFlights); // Allocate here
.
.
.
deAllocFlights(flight, totalFlights); // Error: Deallocate here
fclose(file);
}
Function allocFlights
void allocFlights(Flight **flight, int totalFlights) {
for (int i = 0; i < totalFlights; i++) {
flight[i] = (Flight*) malloc(sizeof(Flight) * 60);
std::cout << flight[i] << " " << i << std::endl; // Print out memory address
}
}
Function deallocFlights
void deAllocFlights(Flight** flight, int totalFlights) {
for (int i = 0; i < totalFlights; i++) {
std::cout << flight[i] << " " << i << std::endl; // Print out memory address
free (flight[i]);
}
}
Main:
int main() {
Flight *flight;
getAllFlights(&flight);
free(flight);
return 0;
}
You're deallocating your first flight twice. So the second time you deallocate it, the system tells you that it hasn't been allocated because, although it was allocated, it was also deallocated. You don't need to call free(flight); at the end because you already deallocated all flights in deAllocAllFlights(). As mentioned by David Schwartz in the comments, this is because flight[0] is the same as *flight (or as he put it *(flight + 0)).
There is missing one star everywhere.
The code works with the original variable as array of pointers to Flight (or pointer to pointers to Flight). Therefore it has to be defined with double star:
int main() {
Flight **flight;
getAllFlights(&flight);
free(flight);
return 0;
}
And the same for every function:
void getAllFlights(Flight ***flight) {
...
*flight = (Flight**) malloc(sizeof(Flight*) * totalFlights);
void allocFlights(Flight ***flight, int totalFlights) {
for (int i = 0; i < totalFlights; i++) {
// dereference the pointer first and then access array:
(*flight)[i] = (Flight*) malloc(sizeof(Flight));
void deAllocFlights(Flight*** flight, int totalFlights) {
for (int i = 0; i < totalFlights; i++) {
std::cout << (*flight)[i] << " " << i << std::endl; // Print out memory address
// dereference the pointer first and then access array
free ((*flight)[i]);
The original code accessed directly the pointer to the variable defined in main function and used it as an array which meant it went to the address behind the variable for index 1 and even more with higher indices.
Also note, that flights is much better name for the variable and all the other parameters as it's actually array. That would make the code more clear and potentially give better chance to avoid mistakes like this.

Memory leak error?

For a simple assignment to do with dynamic memory and copy constructors, my prof has assigned us a simple assignment, but I get an error during the second time my delete [] happens.
header file:
class Stream {
int len;
char *hold;
char* newmem(int);
public:
Stream ();
Stream (int);
Stream(const char *);
~Stream ( );
void operator=(const Stream &);
Stream(const Stream &);
friend void show(Stream);
void operator<<(const char*);
};
it should be fairly simple. here is my code:
#include <iostream>
#include <new>
#include <cstring>
using namespace std;
#include "stream.h"
char* Stream::newmem(int x) {
char * tmp;
try {
tmp = new char[x];
}
catch(std::bad_alloc) {
tmp = NULL;
}
if(tmp)
cout << "newmem: " << (void *) tmp << endl;
return tmp;
}
Stream::Stream ( ) {
len = 1000;
hold = newmem(len);
if (hold)
strcpy (hold, "");
}
Stream::Stream(int n) {
len = n;
hold = newmem(len);
if (hold)
strcpy (hold,"");
}
Stream::Stream(const char * dat) {
len = strlen(dat) +1;
hold = newmem(len);
if (hold)
strcpy(hold,dat);
}
Stream::Stream(const Stream &from) {
cout << "in the copy constructor, allocating new memory..." << endl;
cout << "original pointer address is: " << (void *) from.hold << endl;
cin.get( );
len=from.len;
hold=newmem(len +1);
cout << "new pointer address is: " << (void *) hold << endl;
cin.get( );
if(hold)
strcpy (hold,from.hold);
}
Stream::~Stream ( ) {
cout << "destruct: " << (void *) hold << endl;
cin.get( );
if (hold)
delete [] hold;
}
void Stream::operator= (const Stream &from) {
if(hold)
delete [ ] hold;
len = from.len;
hold=newmem(len +1);
if (hold)
strcpy(hold,from.hold);
}
void show (Stream prt) {
cout << "String is: " << prt.hold << endl << "Length is: " << prt.len << endl;
}
void Stream::operator<< (const char *data) {
int dlen = strlen(data);
for (int i=0 ; i<=len && i<=dlen ; i++) {
hold[i] = data[i];
}
}
int main( ) {
char data[ ] = "Growing up it all seems so one-sided;"
"Opinions all provided;"
"The future pre-decided;"
"Detached and subdivided;"
"In the mass production zone!"
"-Neil Peart- \"Subdivisions\"";
Stream x1, x2(25), x3;
x1 << data;
x2 << data;
show(x1);
show(x2);
x3 = x2;
show(x3);
return 0;
}
and my output / error:
in the copy constructor, allocating new memory...
original pointer address is: 0x804c008
new pointer address is: 0x804c808
String is: Growing up it all seems so one-sided;Opinions all provided;The future pre-decided;Detached and subdivided;In the mass production zone!-Neil Peart-Subdivisions"
Length is: 1000
destruct: 0x804c808
in the copy constructor, allocating new memory...
original pointer address is: 0x804c3f8
new pointer address is: 0x804c808
String is: Growing up it all seems so
Length is: 25
destruct: 0x804c808
*** glibc detected *** a.out: free(): invalid pointer: 0x0804c808 ***
The for loop in the operator<< has two off-by-one errors:
for (int i=0 ; i<=len
allows i==len, but the only valid indices of hold are 0..(len-1). So, you can write one off the end.
Secondly, as thiton pointed out, it doesn't copy the \0 terminator even if there is space.
A correct implementation might look like:
void Stream::operator<< (const char *data) {
int source_len = strlen(data);
int copy_len = min(source_len, len-1); // allow for terminator
for (int i=0; i<copy_len; i++) {
hold[i] = data[i];
}
hold[copy_len] = '\0';
}
although it'd be better practise to simply use strncpy.
Note that the idiom of using half-open (or one-past-the-end) ranges is standard not only in direct array indexing, but also with C++ iterators. So, you should always expect to see
for (i=0; i<n; ++i) {
or
for (i = begin; i != end; ++i) {
and should generally treat closed-range loops like yours as a smell that warrants further investigation.
First a little self-help advice: The most important tool for catching memory access errors is valgrind. Run it on your program, and you'll get a warning every time you try to access unallocated or uninitialized memory. It's no substitute for knowledge, but the next best thing.
While I get different output than you get, errors seem to interact here:
The operator<< has an off-by-one error in the range check. It writes one byte too much (hold[len]).
operator<< does never write the terminating null byte. Both errors are invoked by x2 << data.
When the copy constructor tries to copy the string from x2, strcpy finds no terminating null byte and both reads right off the end of x2.hold and writes past the end of x3.hold. The latter has the potential for unbounded corruption and probably caused your error.
Whenever you deal with C strings, make very, very sure to get termination right. The fixed version is:
void Stream::operator<< (const char *data) {
int dlen = strlen(data);
hold[len-1] = 0;
for (int i=0 ; i < len-1 && i <= dlen ; i++) {
hold[i] = data[i];
}
}
Or, using the std library:
void Stream::operator<< (const char *data) {
strncpy(hold, data, len);
hold[len-1] = 0;
}

Why does array created with 'new' become set to NULL?

I have something like this: A class with a member function which allocates some memory. Why on exit of the function, does the pointer become set to point at NULL?
class A
{
private:
int* memoryblock;
public:
void assignsome(int n);
};
void A::assignsome(int n)
{
memoryblock = new int[n]; // At this point, debugger suggests memoryblock is not pointing to null.
}
// On exit of this function, memoryblock points to null!
On request: Here is the full breakdown:
int FileHandler::PerValueMemoryBlockRead(char* delimarray, unsigned int sizeofarray)
{
// File Opened and mValues_n calculated.
mValues = new int[mValues_n + 1];
mValuesAllocated = true;
// Assignment of the contents of mValues is done.
mValues[next_value_pos] = 0x0; // Last int set to zero. /// next_value_pos is an int which is incremented. (Code Removed because there is no point showing it.)
return 0;
}
void FileHandler::SerialPrint()
{
if(mValuesAllocated){
std::cout << "Address:" << mValues << std::endl;
std::cout << "Size=" << mValues_n << "B" << std::endl;
for(ull pr = 0; pr < mValues_n; pr ++){
std::cout << (int)mValues[pr] << " ";
}
std::cout << std::endl;
}
else{
std::cout << "Nothing to print. 'PerValueMemoryBlockRead' has not yet been called." << std::endl;
}
}
Then inside main:
if((!datahandle.PerValueMemoryBlockRead(delimarray, 3))
&& (!converthandle.PerValueMemoryBlockRead(delimarray, 3))
&& dataoutput.is_open()){
dataoutput.seekp(0, std::ios::beg);
// Code
converthandle.SerialPrint(); // SEG FAULT
datahandle.SerialPrint(); // SEG FAULT
// End Code
If you put the breakpoint there, the debugger still hasn't run the line.
Continue to the next line to see it assigned.
The debugger can be a bit misleading in such cases. In fact the pointer is not NULL, debugger is simply confused and don'y know which A are you talking about. I suggest using debug printing when in doubt in similar cases.
You should see the instance of A has a value memoryblock not equal to NULL after calling assignsome:
class A
{
private:
int* memoryblock;
public:
void assignsome(int n);
};
void A::assignsome(int n)
{
memoryblock = new int[n];
}
int main () {
A a;
a.assignsome(5);
return 0; // breakpoint here - a.memoryblock isn't NULL
}

Dynamic Memory Allocation for Dictionary

Hi there I need to Build something like a dictionary and each word according to my code can have 100 meanings, but maybe it has only 5 meanings then I will be allocating 95 extra space for nothing or maybe it has more than 100 meanings then the program will crash, I know the vector class is very easy and could be good use of, but the task is almost building my own vector class, to learn how it works. Thus **meanings and some other stuff remain the same and here is my code, Also I know I am causing memory leakage, how can I delete properly? :
#include <iostream>
#include <string>
#include <cstring>
using namespace std;
class Expression {
char *word_with_several_meanings; // like "bank", "class"
char **meanings; // a pointer to a pointer stores all meanings
int meanings_ctr; // meanings counter
//-----------FUNCTIONS------------------------------------------------
public:
void word( char* = NULL );
void add_meaning(char* = NULL);
char* get_word();
int get_total_number_of_meanings();
char* get_meaning(int meanx = 0);
Expression(int mctr = 0); // CTOR
~Expression(); // DTOR
};
Expression::Expression(int mctr ) {
meanings_ctr = mctr; // Setting the counter to 0
meanings = new char * [100]; // Allocate Space for 100 meanings
}
Expression::~Expression() {
delete [] meanings; // Deleting the memory we allocated
delete [] word_with_several_meanings; // Deleting the memory we allocated
}
void Expression::word( char *p2c )
{
word_with_several_meanings = new char[strlen(p2c)+1];
// copy the string, DEEP copy
strcpy(word_with_several_meanings, p2c);
}
void Expression::add_meaning(char *p2c)
{
//meanings = new char * [meanings_ctr+1];
meanings[meanings_ctr] = new char[strlen(p2c)+1];
strcpy(meanings[meanings_ctr++],p2c);
}
char * Expression::get_meaning( int meanx )
{
return *(meanings+meanx);
}
char * Expression::get_word()
{
return word_with_several_meanings;
}
int Expression::get_total_number_of_meanings()
{
return meanings_ctr;
}
int main(void) {
int i;
Expression expr;
expr.word("bank ");
expr.add_meaning("a place to get money from");
expr.add_meaning("b place to sit");
expr.add_meaning("4 letter word");
expr.add_meaning("Test meaning");
cout << expr.get_word() << endl;
for(int i = 0; i<expr.get_total_number_of_meanings(); i++)
cout << " " << expr.get_meaning(i) << endl;
Expression expr2;
expr2.word("class");
expr2.add_meaning("a school class");
expr2.add_meaning("a classification for a hotel");
expr2.add_meaning("Starts with C");
cout << expr2.get_word() << endl;
for( i = 0; i<expr2.get_total_number_of_meanings(); i++)
cout << " " << expr2.get_meaning(i) << endl;
Expression expr3;
expr3.word("A long test ... ");
char str[] = "Meaning_ ";
for (int kx=0;kx<26;kx++)
{
str[8] = (char) ('A'+kx);
expr3.add_meaning(str);
}
cout << expr3.get_word() << endl;
for(i = 0; i < expr3.get_total_number_of_meanings(); i++)
cout << " " << expr3.get_meaning(i) << endl;
return 0;
}
When you are allocating a multi dimensional array with new then you are allocating it with a loop, e.g.
char **x = new char*[size]
for (int i = 0; i < N; i++) {
x[i] = new int[size];
}
So you also have to delete it in this fashion:
for (int i = 0; i < N; i++) {
delete[] x[i];
}
delete[] x;
Thus when you're having arbitrary sizes of your array you'll have to store them somewhere for using them within the destructor.
delete [] meanings; // Deleting the memory we allocated
won't get rid of your memory allocated, only the pointers themselves.
To free up the actual memory, you will need to iterate through your meanings array, and delete [] each element in it.
Something like:
for (int i = 0; i < meanings_ctr; ++i)
{
delete [] meanings[meanings_ctr];
meanings[meanings_ctr] = NULL;
}
delete [] meanings;
--
For the problem of what to do if you get more than 100 meanings (or in general when your collection is full), the standard technique is to allocate a new array that is double the size (which you can do since it is dynamic), copy your existing collection into that one, and then dispose of your existing one.
I'd use a simple linked list (this is simplified, not complete and untested; also there should be proper getters/setters and stuff):
class Meaning {
char text[20];
Meaning *next;
Meaning(const char *text) : next(0) {
strcpy(this->text, text);
}
}
class Word {
char text[20];
Meaning *first;
Meaning *last;
Word(const char *text) : first(0), last(0) {
strcpy(this->text, text);
}
~Word() {
Meaning *m = first, *n;
while(m) {
n = m->next;
delete m;
m = n;
}
}
void AddMeaning(const char *text) {
if (last) {
last = last->next = new Meaning(text);
}
else {
first = last = new Meaning(text);
}
}
void print() {
printf("%s:\n\t", text);
Meaning *m = first;
while (m) {
printf("%s, ", m->text);
m = m->next;
}
}
}