2 Dimension Arrays memory segment fault in C++ - c++

I made dynamic allocation and array initialization functions with cpp, but I got a segmentation error The code I wrote is below.
#include <iostream>
#define User_Height 100
#define User_Width 100
using namespace std;
void Creat_Array(int** _pp_Created_Array)
{
_pp_Created_Array = new int*[User_Width];
for (int x = 0; x < User_Height ; x++)
{
_pp_Created_Array[x] = new int[User_Height];
}
if(_pp_Created_Array == NULL)
{
cout<<"""fail to alloc memory.""" <<endl;
return;
}
else
{
cout << "[_pp_Created_Array] memory first address : ";
cout << _pp_Created_Array << endl << endl;
}
}
void Initialize_Array(int** _pp_Initialized_Array)
{
for (int x = 0; x < User_Width; x++)
{
for (int y = 0; y < User_Height; y++)
{
_pp_Initialized_Array[x][y] = 0; //*segment fault*
}
}
}
And I checked the function function created
int main()
{
//debug
int** debugArray = nullptr;
cout << "start creat array" <<endl;
Creat_Array(debugArray);
cout << "start initial array" <<endl;
Initialize_Array(debugArray);
return 0;
}
and compile console is (VScode , g++)
start creat array
[_pp_Created_Array] memory first address : 0x8a6f40
start initial array
The terminal process "C:\Windows\System32\cmd.exe /d /c cmd /C
C:\Users\pangpany\project\PathfinderTest\main" failed to launch (exit code:
3221225477).
But I got a segment fault error in void Initialize_Array(int** _pp_Initialized_Array) function
I can't figure out is there anyone who can help?

So the problem is that you never return the array from the Creat_Array function. and so when you come to use the array you are using an uninitialised variable.
Write Creat_Array with a return value instead of a parameter, like this
int** Creat_Array()
{
int** _pp_Created_Array = ...;
...
return _pp_Created_Array;
}
int main()
{
cout << "start creat array" <<endl;
int** debugArray = Creat_Array();
...
}
Changing a variable inside a function does not change any variable outside the function. debugArray and _pp_Created_Array are two different variables.
Also this code is wrong
if(_pp_Created_Array == NULL)
new never returns NULL so this test will always be false. If new fails it throws an exception, it doesn't return NULL.

Related

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.

Assigning a struct pointer value from struct vector

#include <iostream>
#include <vector>
using namespace std;
struct Sn {
int SnId;
double spentEnergy;
};
class Node {
//other stuff
private:
vector<Sn> SnRecord;
public:
int getBestSn(Sn* bestSn);
void someFunction();
};
int main()
{
Node nd;
nd.someFunction();
return 0;
}
void Node::someFunction() {
//adding some records in vector just for testing purpose
Sn temp;
temp.SnId = 1; temp.spentEnergy = 5;
SnRecord.push_back(temp);
temp.SnId = 2; temp.spentEnergy = 10;
SnRecord.push_back(temp);
temp.SnId = 2; temp.spentEnergy = 10;
SnRecord.push_back(temp);
cout << "Size of SnReocord is " << SnRecord.size() << endl;
//choosing best sn
Sn *bestSn;
int returnCode = -1;
returnCode = getBestSn(bestSn);
if (returnCode == 0){ //means there is a best SN
cout<< "Found best SN with id = "<< bestSn->SnId << endl;
}
else {
cout <<"NO SN "<< endl;
}
}
int Node::getBestSn(Sn* bestSn) {
int tblSize = (int)SnRecord.size();
if (tblSize == 0)
return -1;
//here i have to assign *bestSn a selected value from vector
//suppose SnRecord[2] is best Sn
cout << "Best sn id is " << SnRecord[2].SnId<< endl; //works OK,
bestSn = &SnRecord[2]; ///// giving me core dump ERROR in my own program but in this simplified version it only gives wrong value
return 0;
}
The output now is:
Size of SnReocord is 3
Best sn id is 2
Found best SN with id = 520004336
In my own program it gives me Core dump error, if I comment this line (and make proper other comments according to function call), the error is gone and simulation executes normally.
I saw examples with arrays, the work if a pointer is assigned a value in this way:
int numbers[5];
int * p;
p = &numbers[2]; //works OK.
but for vectors its not working. Or may be its problem of vector of structures, I'm unable to figure out. Any suggestions?
Ok actually the problem is solved by using suggestion of Sn* & bestSn. But I don't understand this solution. Why can't I pass a pointer variable and it saves a pointer value in it which latter could be accessed?

How to create and increase the size of an array at runtime in C++

I want to create an array whose size I will only know at runtime, and then further increase that size during execution of the program.
This is from an /r/dailyprogrammer challenge which can be found here https://www.reddit.com/r/dailyprogrammer/comments/3twuwf/20151123_challenge_242_easy_funny_plant/
MSVisual gives me the error std::badd_array_new_length which means that it's having trouble instantiating the array?
I'm so tired with oftentimes copying code letter for letter from websites where it works and I constantly get errors. Is Visual a bad platform for learning C++? Should I try QT?
#include <iostream>
#include <string>
void main(int argc, char* argv[]) {
int currentPlants = std::stoi(argv[2]), targetPeople = std::stoi(argv[1]), currentProduce = 0, week = 0;
int * plants;
plants = new int[currentPlants];
for (int i = 0; i < currentPlants; i++) {
plants[i] = 0;
}
if (plants == nullptr) EXIT_FAILURE;
while (currentProduce < targetPeople) {
currentProduce = 0;
for (int i = 0; i < currentPlants; i++) {
currentProduce += plants[i];
plants[i]++;
}
if (currentProduce >= targetPeople) break;
else {
plants = new int[currentProduce];
for (; currentPlants < currentProduce; currentPlants++) {
plants[currentPlants] = 0;
}
}
week++;
}
std::cout << week;
}
You should use an std::vector.
As a summary :
// Create an array of size 10
std::vector<int> my_vector(10);
// Add '3' to my_vector
my_vector.push_back(3);
// Remove the last element
my_vector.pop_back();
Explanation and example here : www.cplusplus.com/reference/vector/vector/
Edit : you don't need to specify the array size when you construct your object.
// Create an array
std::vector<int> my_vector;
You can't increase the size of an array at runtime. You can create a new bigger array, and copy the contents of the old array to the new array.
The problem with your code is that on the first pass through plants all of your plants[x] are zero. You add all of these together and get zero => currentProduce == 0. You then try to new plants[currentProduce aka 0] which is illegal.
Your second problem is that each time you new you create a new array discarding the old values; new creates a new array, it doesn't know anything about the old one.
I rewrote your code using std::vector, which fixes the crash but produces an endless loop because on the first pass, currentProduce comes out to zero so the array is truncated.
#include <iostream>
#include <string>
#include <vector>
int main(int argc, const char* argv_real[])
{
const char* argv[] = { "programname", "5", "25" };
int currentPlants = std::stoi(argv[2]), targetPeople = std::stoi(argv[1]), currentProduce = 0, week = 0;
std::cout << "targetPeople = " << targetPeople
<< ", currentPlants = " << currentPlants
<< "\n";
std::vector<int> plants;
// Option 1:
// plants.resize(currentPlants);
// Option 2:
for (auto i = 0; i < currentPlants; ++i) {
plants.push_back(0);
}
while (currentProduce < targetPeople) {
std::cout << "cp: " << currentProduce
<< ", tp: " << targetPeople
<< "\n";
currentProduce = 0;
// plantCount is a reference to plants[i] for each i
for (auto& plantCount : plants) {
std::cout << plantCount << ", ";
currentProduce += plantCount;
plantCount++;
}
std::cout << " cp: " << currentProduce << "\n";
if (currentProduce >= targetPeople)
break;
// Option 1:
plants.resize(currentProduce);
// Option 2:
// while (currentPlants < currentProduce) {
// plants.push_back(0);
// }
week++;
}
std::cout << week;
}
Live demo: http://ideone.com/xGpoF6
Outside of using std::vector, you would need to allocate a new array on the heap, copy the contents over, and delete the old one. Then point your int* to the newly allocated array.
This wouldn't technically change the array size, but those accessing the object would see it as though it was changing.
This is dangerous:
int * plants;
plants = new int[currentPlants];
for (int i = 0; i < currentPlants; i++) {
plants[i] = 0;
}
if (plants == nullptr) EXIT_FAILURE;
This is what happens (if you are lucky):
the program attempts to create some memory and returns nullptr if it can't
the program then uses the memory in a loop even if nullptr was returned. (If nullptr was returned this will crash the program, silently corrupt the memory so you get the wrong results or otherwise doing something you don't want)
the program then checks to see if nullptr was returned.
If you are unlucky the compiler does time travel and destroys the entire universe. I am not kidding, have a look at:
https://blogs.msdn.microsoft.com/oldnewthing/20140627-00/?p=633
Undefined behavior causing time travel

Why does returning a data structure rather than a pointer mess with the integrity of my data?

I'm building a sparse matrix class that holds two arrays (row and column) of pointers to doubly linked lists (down and right). Sort of like this:
rows
c0123456789
o1
l2
u3
m4 A-->B-->
n5 | |
s6 | V
7 V D-->
8 C-->
9
Both arrays are initialized to have nullptr in every space until something is inserted in that place.
I have a function "readFile" that reads in objects from a text file and inserts them into this sparse matrix. For some reason, before this function returns, all of the data in it is fine, but after I return, I get random memory locations in my arrays. Here is main.cpp
#include <iostream>
#include <string>
#include <fstream>
#include "sparseMatrix.h"
using namespace std;
class basic
{
private:
int x, y;
string word;
basic *down;
basic *right;
public:
basic(int x, int y, string word)
{
this->x = x;
this->y = y;
this->word = word;
down = nullptr;
right = nullptr;
}
int getX()
{
return x;
}
int getY()
{
return y;
}
basic *getRight()
{
return right;
}
void setRight(basic *newRight)
{
right = newRight;
}
basic *getDown()
{
return down;
}
void setDown(basic *newDown)
{
down = newDown;
}
void print()
{
cout << "X: " << x << ", Y: " << y << ", word: " << word << ".\n";
}
};
sparseMatrix<basic> readFileBROKEN(string pathToFile);
sparseMatrix<basic> *readFile(string pathToFile);
int main()
{
cout << "Working:\n\n";
sparseMatrix<basic> *workingMatrix = readFile("C:/users/jmhjr/desktop/testdata.txt");
cout << "After returning, here are all the locations that are NOT nullptr:\n";
workingMatrix->printyArray();
cin.get();
cout << "Not working:\n\n";
sparseMatrix<basic> brokenMatrix = readFileBROKEN("C:/users/jmhjr/desktop/testdata.txt");
cout << "After returning, here are all the locations that are NOT nullptr:\n";
brokenMatrix.printyArray();
cin.get();
delete workingMatrix;
}
sparseMatrix<basic> readFileBROKEN(string pathToFile)
{
ifstream inputFile;
inputFile.open(pathToFile);
if (inputFile.fail())
{
cout << "Couldn't open " << pathToFile << "!\n";
exit(-1);
}
sparseMatrix<basic> matrix(100, 100);
while (!inputFile.eof())
{
int x, y;
string word;
inputFile >> x >> y >> word;
basic data(x, y, word);
matrix.insert(data);
}
cout << "Before returning, here are all the locations that are NOT nullptr:\n";
matrix.printyArray();
cout << "press ENTER to return\n";
cin.get();
return matrix;
}
sparseMatrix<basic> *readFile(string pathToFile)
{
ifstream inputFile;
inputFile.open(pathToFile);
if (inputFile.fail())
{
cout << "Couldn't open " << pathToFile << "!\n";
exit(-1);
}
sparseMatrix<basic> *matrix = new sparseMatrix<basic>(100, 100);
while (!inputFile.eof())
{
int x, y;
string word;
inputFile >> x >> y >> word;
basic data(x, y, word);
matrix->insert(data);
}
cout << "Before returning, here are all the locations that are NOT nullptr:\n";
matrix->printyArray();
cout << "press ENTER to return\n";
cin.get();
return matrix;
}
and here is sparseMatrix.h:
template <class dataType>
class sparseMatrix
{
private:
//The dimensions of the sparse matrix.
int width;
int height;
//Dynamic array of pointers to heads of linked lists.
dataType** xArray;
dataType** yArray;
public:
//Constructor. Sets everything in the two arrays to nullptr.
sparseMatrix(int height, int width)
{
this->width = width;
this->height = height;
xArray = new dataType*[width];
yArray = new dataType*[height];
for (int row = 0; row < height; row++)
{
this->yArray[row] = nullptr;
}
for (int col = 0; col < width; col++)
{
this->xArray[col] = nullptr;
}
}
//Deconstructor. First goes through the matrix and looks for every city it can find, and deletes
//all of those. Then when it's done, it deletes the two dynamic arrays.
~sparseMatrix()
{
dataType *currentdataType;
dataType *next;
for (int row = 0; row < height; row++)
{
currentdataType = yArray[row];
while (currentdataType != nullptr)
{
next = currentdataType->getRight();
delete currentdataType;
currentdataType = next;
}
}
delete [] yArray;
delete [] xArray;
}
//Creates a copy of the data we are passed, then creates links to this copy.
void insert(dataType data)
{
//Make sure the data is valid.
if (data.getX() < 0 || data.getX() >= width || data.getY() < 0 || data.getY() >= height)
{
std::cout << "That dataType doesn't fit into the sparse matrix!\n";
data.print();
std::cin.get();
}
else
{
//Copy the data we were passed.
dataType *newData = new dataType(data);
//Easy case. If nothing is in this row, set yArray[row] to the address of this data.
if (yArray[data.getY()] == nullptr)
{
yArray[data.getY()] = newData;
}
//Not so easy case. Move forward (right) until we find the right location, then set links.
else
{
dataType *current = yArray[data.getY()];
while (current->getRight() != nullptr)
{
current = current->getRight();
}
current->setRight(newData);
}
//Easy case. If nothing is in this col, set xArray[col] to the address of this data.
if (xArray[data.getX()] == nullptr)
{
xArray[data.getX()] = newData;
}
//Not so easy case. Move forward (down) until we find the right location, then set links.
else
{
dataType *current = xArray[data.getX()];
while (current->getDown() != nullptr)
{
current = current->getDown();
}
current->setDown(newData);
}
}
}
void printyArray()
{
for (int r = 0; r < height; r++)
{
if (yArray[r] != nullptr)
{
std::cout << r << ' ';
//yArray[r]->print();
}
}
}
};
readFile reads everything in from a file that looks like this:
0 0 hello
5 2 world
6 8 foo
9 5 bar
...
As expected, before returning, the only locations that are NOT nullptr are the ones that I have inserted into. (0, 2, 8 and 5). However when the function returns, EVERY SINGLE location in the array is not nullptr. I added a second function which returns a pointer to dynamically allocated sparseMatrix object, rather then returning the object itself, and this fixed it. However, I don't understand why. It seems like these two functions should behave identically the same way.
Also, the part that is most confusing to me, why does this run perfectly fine in Xcode, but not in Visual Studio?
tomse's answer is correct and gives the why and a fix, but it's an unnecessarily expensive fix for this problem. His suggestion of the copy constructor also solves numerous future problems such as the classics Why did my vector eat my data? and Dude, where's my segfault? Make the copy constructor. Don't use it unless you have to.
I think Andras Fekete got the problem right, but his post is kind of garbled. His solution is bang on, though.
Define your function like this:
bool readFile(string pathToFile, sparseMatrix<basic> & matrix)
Remove the definition of matrix inside the function in favour of the one passed in.
Return false on error so you know the matrix is bad (or use exceptions).
Create the matrix in the calling function and pass it into the revised reader function.
sparseMatrix<basic> matrix(100, 100);
if readFile("C:/users/jmhjr/desktop/testdata.txt", matrix);
That puts you right back where you were with the pointer version, but without the pointer and without having to do the extra work of copying data you didn't need to copy.
Your function:
sparseMatrix<basic> readFileBROKEN(string pathToFile)
returns a copy of the object (which is OK), but sparseMatrix does not define a copy constructor, so the default generated will be used which creates a shallow copy by just copying the adresses inside the returned object.
But the memory where the address points to is deleted when you leave your function (because the destructor of the locally created object is called).
To solve this you have to define your own copy contructor in sparseMatrix which copies all the content of the object.
sparseMatrix(const sparseMatrix& rhs) :
width(rhs.width),
height(rhs.height),
xArray(nullptr),
yArray(nullptr)
{
... and now copy all the content from rhs.xArray to this->xArray,
(same for yArray)
}
The problem is that you're allocating 'matrix' inside both of the readFile functions. Upon returning from the function, both variables are deallocated. However, returning the value (eradFile) the matrix is copied into your variable of the calling function, whereas returning the pointer (readFileBROKEN) is just returning the address where the matrix used to be stored.
To fix this, you should allocate the 'matrix' variable, and pass in a reference to the function. Then the function can return a void while stuffing the matrix properly.

Why do I get a segmentation fault when using pthread_join?

Here is the code I have, it compiles and runs using g++ but I get a segmentation fault. I know it happens around the pthread_join statement but I cant figure out why.
#include <iostream>
#include <stdio.h>
#include <fstream>
#include <pthread.h>
#include <stdlib.h>
#include <sstream>
using namespace std;
struct data{
string filename;
int x;
int y;
};
void *threadFunction(void *input){
data *file = (data *) input;
string filename = file->filename;
ifstream myFile;
int xCount = 0;
int yCount = 0;
myFile.open(filename.c_str());
string line;
while(myFile >> line){
if(line == "X"){
xCount++;
}else if(line == "Y"){
yCount++;
}
}
file->x = xCount;
file->y = yCount;
return (void *) file;
}
int main(){
pthread_t myThreads[20];
data *myData = new data[20];
for(int i = 0; i < 20; i++){
ostringstream names;
names << "/filepath/input" << i+1 << ".txt";
myData[i].filename = names.str();
myData[i].x = 0;
myData[i].y = 0;
}
for(int i = 0; i < 20; i++){
int check = pthread_create(&myThreads[i], NULL, threadFunction, (void *) &myData[i]);
if(check != 0){
cout << "Error Creating Thread\n";
exit(-1);
}
}
int xCount = 0;
int yCount = 0;
for(int i = 0; i < 20; i++){
data* returnedItem;
pthread_join(myThreads[i], (void**) returnedItem);
xCount += returnedItem->x;
yCount += returnedItem->y;
}
cout << "Total X: " << xCount << "\n";
cout << "Total Y: " << yCount << "\n";
}
Am I not calling return properly from my threadFunction? I've been trying a bunch of different things and I still don't know what's going on...any help would be greatly appreciated! (the text file I open contain either an X or Y per line. My goal is to count the total number of Xs and Ys in 20 text files)
Second argument of pthread_join will be used to return, return value of the thread, so somewhere inside pthread_join we have a code that call *secondArgument = thread_return_value, but lets look at what you are doing here:
// You are not initializing returnedItem, so it contain some garbage value
// For example 0x12345678
data* returnedItem;
// Now you cast that garbage to (void**), and pthread_join will call
// *(0x12345678) = thread_return_value that will cause segmentation fault
pthread_join(myThreads[i], (void**) returnedItem);
But you want return value to be copied to returnedItem, am I right? in case that you answer is yes you should pass address of returnedItem to pthread_join so it can copy it there. So change your call to:
pthread_join(myThreads[i], (void**) &returnedItem);
pthread_join(myThreads[i], (void**) returnedItem);
should be
pthread_join(myThreads[i], (void**) &returnedItem);
You're asking join to set the value of returnedItem to be whatever void* your thread function returned ... so you need to give the address of returnedItem.
The second argument to pthread_join() is a void** into which the result is to be stored. You are passing a random value, however. This could should rather look something like this:
void* result;
pthread_join(myThread[i], &result);
data* returnedItem = static_cast<data*>(result);
Of course, this assumes that a data* was, indeed, returned.