c++ Access violation writing location 0x00000000 - c++

I have the following code:
In Client.cpp there is the constructor that is doing memory allocation for the array "conturi" of type ContBancar.
Client::Client(string nume, string prenume, string adresa)
{
this->nume = nume;
this->prenume = prenume;
this->adresa = adresa;
nrCont = 0;
ContBancar** conturi = new ContBancar*[50];
}
Then there is a method that is adding a account in the "conturi" array:
void Client::adaugaCont(ContBancar* contNou)
{
conturi[nrCont++] = contNou;
}
This is my code in Main.cpp:
ContBancar ron1 ("1.r", 0, Banca::RON);
Client ioana ("Pop", "Ioana", "Str Dorobantilor 3/4");
ioana.adaugaCont(&ron1);
But it gives me the access violation error at runtime, like the array 'conturi' has no memory allocated. I don't understand why, because the memory should be allocated in the constructor.
Could anyone help me with this?

Client::Client(string nume, string prenume, string adresa)
{
this->nume = nume;
this->prenume = prenume;
this->adresa = adresa;
nrCont = 0;
//here is your problem!
ContBancar** conturi = new ContBancar*[50];
}
You redefine conturi as a new array, with the pointer to it stored in the local scope of the constructor.
Change the line to:
conturi = new ContBancar*[50];
and you will then have the object's conturi pointer pointing to the allocated memory.
This will also solve the memory leak you have introduced.
(pointer to heap goes out of scope. memory on heap is leaked)
Or even better, use a std::vector.
In Class definition:
std::vector<ContBancar> conturi;
You don't have to manage the memory yourself with new and delete and you are not restricted to a fixed number of elements either.

You're declaring a new pointer variable with the following line:
ContBancar** conturi = new ContBancar*[50];
and the pointer variable will get destroyed at the end of the function call and leak memory leaving any other same-name member variable untouched.
You should rather use the member variable conturi(assuming you have one from the rest of the code):
Client::Client(string nume, string prenume, string adresa)
{
this->nume = nume;
this->prenume = prenume;
this->adresa = adresa;
nrCont = 0;
conturi = new ContBancar*[50];
}
or you can use a std::vector<ContBancar> conturi member variable which might be easier to use and to deal with.
This is a simple reproducer to better understand the problem:
class Client {
public:
int** conturi = 0;
void function() {
int** conturi = new int*[50];
}
};
int main()
{
Client obj;
obj.function();
if(obj.conturi == 0)
std::cout << "this is still zero"; // This will get printed
}
Example

Related

Exception thrown at 0x0037A5C2 project.exe: 0xC0000005: Access violation writing location 0xDDDDDDDD at the end of the program

I have encountered this runtime exception at the very end of the program by simply creating an instance of the specified class, so I presume the issue lies with either the constructor, copy constructor, copy assignment operator or destructor. I have read up on and followed the rule of three to the extent of my limited cpp knowledge.
Source.cpp
#include "Header.h"
#include <iostream>
using namespace std;
int main() {
string command = "CREATE TABLE table_name IF NOT EXISTS ((column_1_name,type,default_value), (column_2_name,type,default_value))";
string columns[20] = { "column_1_name,type,default_value", "column_1_name,type,default_value" };
string commandData[9] = { "table_name", "IF NOT EXISTS" };
CommCREATETABLE comm(command, columns, commandData, 2, 2);
}
Relevant code from Header.h
class CommCREATETABLE {
string fullCommand = "";
string* columns = nullptr;
string* commandData = nullptr;
string tableName = "";
int nrOfColumns = 0;
int nrOfElements = 0;
bool valid = false;
Constructor:
CommCREATETABLE(string command, string* columns, string* commandData, int nrOfRows, int nrOfElements) {
this->setNrOfColumns(nrOfRows);
this->setNrOfElements(nrOfElements);
this->setCommand(command);
this->setColumns(columns);
this->setCommandData(commandData);
this->valid = checkInput(this->commandData, this->columns);
this->setTableName(commandData[0]);
}
Copy constructor, copy assignment operator, destructor:
CommCREATETABLE(const CommCREATETABLE& comm) {
this->setNrOfColumns(comm.nrOfColumns);
this->setNrOfElements(comm.nrOfElements);
this->setCommand(comm.fullCommand);
this->setColumns(comm.columns);
this->setCommandData(comm.commandData);
this->setTableName(comm.tableName);
this->valid = comm.valid;
}
~CommCREATETABLE() {
if (this->columns != nullptr) {
delete[] this->columns;
}
if (this->commandData != nullptr) {
delete[] this->commandData;
}
}
CommCREATETABLE& operator=(const CommCREATETABLE& comm) {
this->setCommand(comm.fullCommand);
this->setColumns(comm.columns);
this->setCommandData(comm.commandData);
this->setTableName(comm.tableName);
this->setNrOfColumns(comm.nrOfColumns);
this->setNrOfElements(comm.nrOfElements);
this->valid = checkInput(this->commandData, this->columns);
return *this;
}
The only setters that deal with dynamic memory allocation are the following:
void setColumns(const string* columns) {
if (this->nrOfColumns >= 0) {
this->columns = new string[this->nrOfColumns];
memcpy(this->columns, columns, this->nrOfColumns * sizeof(string));
}
else throw EmptyCommandException();
}
void setCommandData(const string* commandData) {
if (this->nrOfElements >= 0) {
this->commandData = new string[this->nrOfElements];
memcpy(this->commandData, commandData, this->nrOfElements * sizeof(string));
}
else throw EmptyCommandException();
}
At a quick glance I would say the issue is in your setColumns and setCommandData functions. (I might of course be wrong, I did not try to run the code you presented nor the changes I made -- so there might also be a typo somewhere.)
There you use memcpy to copy the strings into your class. However, internally a C++ string holds a pointer to the actual string, so using memcpy actually only copies that pointer. As a result, once the original string gets deleted, the pointer you copied into your class is no longer valid (as the memory has already been freed). As a result, once your class also gets deleted it attempts to delete memory that has already been freed. That is probably where your error comes from.
In fact, if you added lines to your program where you tried to manipulate your class (after the original input strings have already been deleted), the problem would present itself even sooner, as you would be accessing memory that has already been freed. This would lead to undefined behaviour, which typically ends with a crash at some point.
A quick fix would be to change the way you copy the data, by using = for each string (in that way copying the actual strings into a new location in memory, rather than copying the pointer).
void setColumns(const string* columns) {
if (this->nrOfColumns > 0) { // Creating an array of size 0 is also not a good idea.
this->columns = new string[this->nrOfColumns];
for (int i = 0; i < nrOfColumns; i++) { // You don't need this everywhere.
this->columns[i] = columns[i];
// I don't think naming things the exact same way is good practice.
}
}
else throw EmptyCommandException();
}
void setCommandData(const string* commandData) {
if (this->nrOfElements > 0) { // Creating an array of size 0 is also not a good idea.
this->commandData = new string[this->nrOfElements];
for (int i = 0; i < nrOfElements; i++) { // You don't need this everywhere.
this->commandData[i] = commandData[i];
// I don't think naming things the exact same way is good practice.
}
}
else throw EmptyCommandException();
}
Alternatively, if you want to avoid making copies you should look into move, but I would suggest against this for the time being, if you are still learning. You'll get there soon enough.

Fix Runtime Error with Reverse Array Code using pointers [duplicate]

How do I delete the memory that have been allocated for array models, names? I tried every method but it always crashes when I run it.
int main()
{
vector<Person*> people;
const int PERSON_SZ = 4;
char * names[] = {"Jim", "Fred", "Harry", "Linda"};
int ages[] = { 23, 35, 52, 59 };
for (int i = 0; i < PERSON_SZ; i++)
{
Person * temp = new Person(names[i], ages[i]);
people.push_back(temp);
}
// A vector of Car pointers
vector<Car*> cars;
const int CAR_SZ = 3;
char * models[] = { "Festiva", "Ferrarri", "Prius" };
srand(time(0));
for (int i = 0; i < CAR_SZ; i++)
{
Car * temp = new Car(models[i]);
temp->set_driver(people[rand() % (people.size())]);
temp->set_owner(people[rand() % (people.size())]);
cars.push_back(temp);
}
for (int p = 0; p < people.size(); p++)
{
people[p]->increment_age();
}
for (int c = 0; c < cars.size(); c++)
{
cars[c]->print();
}
delete [] names;
for ( int r = 0; r < CAR_SZ; ++r )
{
delete [] models[r];
}
return 0;
}
You didn't allocate models and names using new, so you cannot delete them.
Both arrays are allocated on the stack and are automatically deleted, when the function returns.
The contents of the (string) arrays (i.e. the strings itselves) are stored in the global data segment and cannot be freed at all. This would also be dangerous because the compiler might use the same string constant at different places in the program.
The models array and the names array are both statically allocated. You didn't use new to create them, you don't need to delete them. You should, however, change their types as follows:
const char * names[] = {"Jim", "Fred", "Harry", "Linda"};
const char * models[] = { "Festiva", "Ferrarri", "Prius" };
because they are pointers to string literals, which are read-only.
The variable names and models are not dynamically allocated, and neither is the data in those arrays. So no need to free them or their contents.
The two vector contains data that need to be free'd on the other hand.
You did not allocate names, and models. You don't need to free or delete them from memory.
As others have answered, this is neither required nor legal...
delete [] names;
Since you didn't new names.
Neither is this...
for ( int r = 0; r < CAR_SZ; ++r )
{
delete [] models[r];
}
Since you didn't new any of the models.
But you do still have some memory leaks!
For each car instance you newed and stored in the cars vector, you need to call delete. Here is one way:
for (std::vector<Car*>::iterator car = cars.begin(), done = cars.end(); car != done; ++car)
{
delete *car;
}
Note that the * there dereferences the iterator, yielding the raw pointer you newed.
The problem with this approach is that it leaves you with a vector full of dangling pointers. You could either reset them in the loop or clear() the vector after the loop has terminated. Perhaps a better approach would be:
while (not cars.empty())
{
delete cars.back();
cars.pop_back();
}
Which deletes each car, then removes its pointer from the vector.
Similarly for each person you newed and stored in people:
while (not people.empty())
{
delete people.back();
people.pop_back();
}
As a rule of thumb, there should be one delete for every new and one delete[] for every new ... []. But you'll do well to learn about smart pointers.
names and models are not pointing heap-allocated area. Don't delete it.
Your code is incomplete. It does not compile. Please enable all warnings and debugging for your compiler, e.g. with g++ -Wall -g if using GCC and improve your code till you get no warning
char * names[] = {"Jim", "Fred", "Harry", "Linda"};
delete [] names;
This is incorrect. You can only delete something that you obtained thru new.

C++ resize array of pointer without STL (vector...)

I got following problem.
I want to resize my array of pointers on structure ( car ) . I got following code.
Class Car{
...
char * Owner_Name;
char * carID
};
Class Register {
...
int CarCNT;
int car_num_default;
Car ** dataBase;
Register ()
{ //constructor
car_num_default = 5 ; //for example;
dataBase = new Car * [car_num_default];
}
};
Now when I add 6th. car I need to resize my array of pointer to car. How should I do that without create any memory leak ? Or memory error ? :)
I tried folowing code but it makes some memory leaks..
void Register:: Add ( const char * carID, const char * owner)
{
if (carCNT == car_num_default) // now it's full array need resize
{
car ** tmp = new car * [carCNT]; //create new array ;
for(int i = 0 ; i < carCNT;i++)
tmp[i] = new car(databaze[i]->car_ID,databaze[i]->owner_name);
free(database); //free memory and than alloc new bigger
database = new car * [car_num_default * 5];
for(int i = 0; i < carCNT; i++)
data_by_RZ[i] = tmp [i];
free(tmp);
car_num_def = car_num_def * 5;
}
databaze[carCNT] = new car(....);
carCNT++;
}
Thanks for any help!
Here's a list of obvious bugs in your memory management:
You allocate with new[] but deallocate with free. See Is there any danger in calling free() or delete instead of delete[]?
On reallocation, you create new car instances and copy the data of existing car objects instead of copying the pointers to the existing car obejcts. This causes all the previous cars objects to leak. This bug is only when copying database to the tmp table. The copy from tmp to the new database would be correct if tmp contained the pointers to the old car objects.
You needlessly create a tmp array and copy the database to it. You should simply create the new, bigger array, copy, deallocate the old and then set the database pointer. This bug does not cause a leak, but is entirely pointless and does waste memory bandwidth.*
* Here's the code as requested:
Car** tmp = new Car*[car_num_default * 5];
for(int i = 0; i < CarCNT; i++)
tmp[i] = database[i];
delete[] database;
database = tmp;
Remember that functions destroy their parameters after the function finishes its execution.
Since you are passing carID and owner as pointers and inserting them into the array, the values are destructed after execution and the pointers placed inside the array become invalid causing the leak. Use pointers only when you want to make a change to the pointer itself but never store it as it will soon be destructed.
It seems that you are using pointers in places you shouldnt or where you don't have to. Here is a simpler version of your code that does the same:
Class Car{
...
char Owner_Name;
char carID;
};
Class Register {
...
int CarCNT;
int car_num_default;
Car * dataBase;
Register ()
{ //constructor
car_num_default = 5 ; //for example;
dataBase = new Car [car_num_default];
}
};
void Register:: Add ( const char carID, const char owner)
{
if (CarCNT == car_num_default) // now it's full array need resize
{
car * tmp = new car [carCNT]; //create new array ;
for(int i = 0 ; i < carCNT;i++)
tmp[i] = new car(dataBase[i].car_ID,dataBase[i].owner_name);
free(dataBase); //free memory and than alloc new bigger
dataBase = new car [car_num_default * 5];
for(int i = 0; i < carCNT; i++)
data_by_RZ[i] = tmp [i];
free(tmp);
car_num_def = car_num_def * 5;
}
Car x(...);
dataBase[CarCNT] = x;
carCNT++;
}
Finally, I have four points to make:
1) This doesnt seem like C++ or you are not using proper naming
2) I am not sure how this code complied since most variable names are incorrect (i tried to fix what i came across).
3) Excessive use of pointers (memory locations in other words) is the main cause of memory leaks. Handle them with care and only use them when you have to.
4) IFFF you have to use pointers that much then add destructors (Anti-constructor) like this ~Car or ~Register on any class that is used as a pointer to signal when the element is destroyed. That way you know where the leak is taking place by writing to the console or handle the destruction gracefully.
Hope that helped

Member Variable Of Type String (Array) Pointer throwing Exception. (C++)

I have instantiated a private member variable in a 'Student' object. It points to an array that I'm dynamically resizing according to number of courses the 'student' is enrolled in.
I'm new to pointers, and I'm probably messing up something to do with the reference to the dynamically declared 'course' array in the heap.
EDIT : Vectors, Lists, or anything other than primitive std:string arrays can't be used.
The following line throws an exception:
void Student::addCourse(std::string course){
numCourses++;
std::string *tempArray = new std::string[numCourses];
for(int i = 0; i <= numCourses - 1; i++){
tempArray[i] = courseList[i]; // <---------- This line...
}
tempArray[numCourses - 1] = course;
courseList = tempArray;
delete []tempArray;
}
Unhandled exception at 0x50A0E89A (msvcr110d.dll) in filename.exe:
0xC0000005: Access violation reading location 0xABABABAB.
The member is declared like so in the header file:
class Student
{
private:
std::string *courseList;
EDIT : Here's the constructor I'm using:
Student::Student(std::string name)
:numCourses(0),
courseList(nullptr),
name(name){}
Any input is appreciated.
Cheers.
Why you don't use a list, like:
List<string> s = new List<string>();
Basically what is wrong with your code is the delete []tempArray; and that is, because before that you make courseList point to the same address that tempArray points to, and then you delete memory stored within tempArray, which means that courseList now points to invalid(recycled, freed) memory.
You should make courseList nullptr(NULL if you don't have C++11-compilant compiler) when in constructor, and then the Student::addCourse can look like this:
void Student::addCourse(std::string course){
numCourses++;
std::string *tempArray = new std::string[numCourses];
for(int i = 0; i < numCourses - 1; i++)
{
tempArray[i] = courseList[i];
}
tempArray[numCourses - 1] = course;
delete[] courseList;
courseList = tempArray;
}
So basically you allocate new memory for the new sequence of strings, and then you assign the old contents from courseList into tempArray, then you assign the new course string into the last place, and you delete the old strings. After that you make courseList point to the same thing tempArray points to.
EDIT:
Changed the -2 into -1 as well as <= into <

C++ - Delete std::string*; heap corruption

I'm relatively new to C++ memory management, and I'm getting this weird error of heap corruption (plus an automatic breakpoint in Visual Studio before it). Here is the offending code:
z_world::z_world(char* name)
{
unsigned int i, skip;
char tmp;
//Load data from file
std::string* data = loadString(name);
//Base case if there is no world data
tiles = NULL;
w = 0;
h = 0;
if(data->length() > 0) {
//Set up the 'tiles' array
for(i = 0; i < data->length(); i++) {
if(data->at(i) == '\n')
h++;
if(h == 0)
w++;
}
tiles = new int[data->length()-h];
//Load Data
skip = 0;
for(i = 0; i < data->length(); i++) {
if(data->at(i) == '\n') {
skip++;
printf("\n");
continue;
}
tmp = data->at(i);
tiles[i+skip] = atoi(&tmp);
printf("%i ",tiles[i+skip]);
}
}
delete data;
}
Here's where I load in the string:
std::string* loadString(char* name)
{
ifstream in(name);
std::string* input = new string();
while(in) {
std::string line;
getline(in,line);
input->append(line);
input->append("\n");
}
in.close();
return input;
}
I get the breakpoint and error inside of "delete data;", which makes me think that "data" gets deleted somewhere before that, but I can't find where it would. For reference, this method is to create an object that contains world data for a game in the form of a virtual 2D integer array (for the ID's of the tiles).
Youre problem is probably here:
tiles[i+skip] = atoi(&tmp);
Problem 1:
It should be -skip
tiles[i - skip] =
Problem 2:
The atoi() command is being used incorrectly (tmp does not contain a string). But also I don't think atoi() is the appropriate method. I think what you are looking for is simple assignment. The conversion from char to int is automatic:
tiles[i - skip] = tmp;
Problem 3:
You are not using objects correctly. In this situation there is no need to generate dynamic objects and create a mess with dynamic memory management. It would be simpler to just to create automatic objects and pass those back normally:
std::string* loadString(char* name)
// ^ Don't do this.
std::string loadString(std::string const& name)
// ^^^^^^^ return a string by value.
// The compiler will handle memory management very well.
In general you should not be passing pointers around. In the few situations where you do need pointers they should be held within a smart pointer object or containers (for multiple objects) so that their lifespan is correctly controlled.
atoi(&tmp);
atoi expects a pointer to a null terminated string - not a pointer to a char
There's no need to dynamically allocate the string in the code you've shown. Change the loadString function to
std::string loadString(char* name)
{
ifstream in(name);
std::string input;
// ...
return input;
}
In the caller
std::string data = loadString( name );
Now there's no need to delete the string after you're done.
Instead of
int *tiles = NULL;
tiles = new int[data->length()-h];
use
std::vector<int> tiles;
tiles.resize(data.length() - h);
Also, if you do need to dynamically allocate objects you should be using smart pointers (std::unique_ptr and std::shared_ptr) instead of raw pointers.
There is a bug in
tiles[i+skip] = atoi(&tmp);
For example, for a string
Hello\n
World\n
and for the loop iteration at the point of i == 10, skip is already 1 (since we have encountered the first \n before) and you are writing to tiles[10 + 1], but tiles only has been allocated as an array with 10 elements.
May be the variable input is local to this function. So after returning from this the memory is freed. So, calling later delete on this string tries to free already freed memory.