Program crashes on deleting array of pointers in struct - c++

Crashes when the delete command comes around. It's supposed make a struct with pointers to arrays, fill them with random numbers, and then deallocate the memory. Works fine until the delete command, in which it crashes with our without the for loop or boolean check.
int main() {
cout << "start" << endl;
//Creating Struct
struct
{
int* ptrarray[10];
bool boolarray[10];
} data;
//Initializing Random Generator
srand ( time(NULL) );
cout << "Initializing: ";
//Allocating Memory and generating random numbers with for loops
for (int i = 0; i < 10; i++)
{
int counter = 0; //Counts numbers set
cout << i << " "; //Counting arrays initialized
data.ptrarray[i] = new int [12582912]; // Memory Allocation
for (int j = 0; j < 12582912; j++)//Number Generating
{
*data.ptrarray[i] = rand() % 899 + 100;
data.ptrarray[i]++;
counter++;
}
//Checking for failed initializations and declaring if success
if (counter == 12582912)
{
data.boolarray[i] = true;
}
else
{
data.boolarray[i] = false;
}
}
cout << endl;
//This is where it always crashes.
for (int i=0; i<10; i++)
{
if (data.boolarray[i] == true)
delete[] data.ptrarray[i];
}
cout << endl;
return 0;
}
I'm using MS Visual studio 2010.

The culprit is this line:
data.ptrarray[i]++;
You are changing the pointer, then using delete [] on the modified pointer. This will not work: you must use delete[] with the exact same pointer you got from new[].
Try
data.ptrarray[i][j] = rand() % 899 + 100;
instead so you don't have to change your pointer.

data.ptrarray[i]++; is the problem.
You're incrementing your reference to the data, but then not resetting it to the start before trying to delete it.

Your problem lies with:
data.ptrarray[i]++;
This is modifying the pointer. When you then attempt to free that modified pointer, it crashes.
You can solve this by using a copy of the pointer to run through the array, or by indexing with thej variable as well:
data.ptrarray[i][j]

Related

Garbage value when trying to remove value from dynamic array

i keep getting garbage value on one of the indexes in the dynamic array when i try to remove a value which was entered by user from a list of elements in the dynamic array.
used pointer as function parameters and replaced the value to be removed with 0 and by using a counter and for loop tried to skip all the 0s but in place of zero theres a garbage value.
#include<iostream>
#include<fstream>
using namespace std;
int size = 0;
int final = 0;
int* read(ifstream& a){
int temp;
a.open("data(1).txt");
while (!a.eof()){
a >> temp;
size++;
}
a.close();
a.open("data(1).txt");
int* arr = new int[size];
for (int i = 0; i < size; i++)
a >> arr[i];
return arr;
}
int* remove(int* a,int search){
for (int i = 0; i < size; i++){
if (a[i] == search)
a[i] = 0;
else final++;
}
int* change = new int[final+1];
for (int i = 0; i < size; i++){
if (a[i] > 0){
change[i] = a[i];
}
else continue;
}
delete[] a;
a = nullptr;
return change;
}
int main(){
int* ptr = nullptr;
int num;
cout << "please enter the number to remove: ";
cin >> num;
ifstream in;
ptr=read(in);
ptr=remove(ptr, num);
for (int i = 0; i < final; i++)
cout << ptr[i] << " ";
cout<<endl;
system("pause");
return 0;
}
There is much to discuss and critize about your code. Also your question is very unclear because we do not have your input file, nor do you tell us what the code should actually do. However, I will leave all "please write actual c++ rather than c without classes" aside and just point you to the one critical mistake:
This loop
int* change = new int[final+1];
for (int i = 0; i < size; i++){
if (a[i] > 0){
change[i] = a[i];
}
else continue;
}
And then this loop
for (int i = 0; i < final; i++)
cout << ptr[i] << " ";
It seems like you want to copy all elements that are >0 to change. Or maybe you want to copy all, its really hard to tell, because broken code is just broken, it does not explain itself. Anyhow...
The first loop leaves all elements change[i] where a[i] <= 0 uninitialized. The values at those indices i are indeterminate. There isn't really a value you can read. Attempting to read an indeterminate value results in undefined behavior.
You are attempting to read all elements of change, but some of them are not initialized, they are indeterminate values. Hence your code has undefined behavior.
There are other situations the will bring your code into bad states, like for example search not begin found in the input array or a[i] > 0 for some i > final. Though, I don't see a possiblity for any input to your code that would not eventually invoke undefined behavior.
You sould use a debugger to see where your code is doing something unexpected.

stack overflow when making a third object for merge sort project c++

So I am making a merge sort program in c++ that is supposed to take 5 arrays of size 10, 100, 1000, 10000, and 100000, and tell how many comparisons are made for each array. I was able to sort all arrays fine, but I ran into a stack overflow when trying to make a third object of my merge sort class. I made the first two objects of my merge sort class without any problems, but when I make a third object of my merge sort class, I get an error that there is a stack overflow. When I debug the program it points me to the .asm file, and since I don't know assembly I'm not sure what to think of this. I've run into this problem in the past, and it's because I forgot to dynamically allocate memory to array's. I looked back and all my array's have been dynamically allocated, so I'm not sure why I am getting this error. Here is my main, I marked what is giving me errors with asterisks. Any help is appreciated, this is my second question on here so don't destroy me please :)
//main.cpp
int main(){
int* tenArray;
int* hundArray;
int* thouArray;
int* tenThouArray;
int*oneHundThouArray;
tenArray = new int[9];
hundArray = new int[99];
thouArray = new int[999];
tenThouArray = new int[9999];
oneHundThouArray = new int[99999];
srand((unsigned int)time(NULL));
//Create arrays filled with random numbers
for (int i = 0; i < ARRAY_TEN; i++) {
tenArray[i] = rand();
}
for (int i = 0; i < ARRAY_HUND; i++) {
hundArray[i] = rand();
}
for (int i = 0; i < ARRAY_THOU; i++) {
thouArray[i] = rand();
}
for (int i = 0; i < ARRAY_TEN_THOU; i++) {
tenThouArray[i] = rand();
}
for (int i = 0; i < ARRAY_ONE_HUND_THOU; i++) {
oneHundThouArray[i] = rand();
}
MergeSort tenSort;
MergeSort hundSort;
//******************************************************************
MergeSort thouSort;//When typed the program will give an error
//******************************************************************
//Here I am just calling my sort function from implementation file:
//sorting 10 array
tenSort.sort(tenArray, 0, ARRAY_TEN - 1);
cout << endl << "Comparisons = " << tenSort.getCount() << endl;
//sorting 100 array
hundSort.sort(hundArray, 0, ARRAY_HUND - 1);
cout << endl << "Comparisons = " << hundSort.getCount() << endl;
//****************************************************************
//sorting thousand array
thouSort.sort(thouArray, 0, ARRAY_THOU - 1);
cout << "comparison = " << thouSort.getCount() << endl;
//****************************************************************
}
getCount just looks like this:
//in implementation
int MergeSort::getCount() {
return count;
}
If it helps the line in the asm file causing the error says:
test dword ptr[eax],eax ;probe page
Do the MergeSort constructors allocate any additional memory? It's possible you're actually running out of memory on the stack. The stack can only contain so much data, and declaring over a hundred-thousand integers multiple times could add up to quite a lot.

A global static array in C++

I've got something like this:
static int n = 0; // global static int
int *arr = new int[n]; // global int*
int randToArray(int arr[], int min, int max) {
srand(time(NULL));
for(int i = 0; i <= n; i++) {
arr[i] = (rand() % max + min);
}
}
void printArray() {
if(n) {
for(int i = 0; i < n; i++)
cout << arr[i] << endl;
} else
cout << "The array hasn't been drawed yet.";
}
And then in the main function I have a menu with a switch and options for getting random numbers and printing the array:
switch(option) {
case 1:
cout << "Set the size of the array: ";
cin >> n;
randToArray(arr, 1, 99);
break;
case 2:
printArray();
wait();
break;
}
I need my array to be available globally in order to use in several other functions.
Everything works except one thing: when I want to print the array I get working properly only 8 first elements. Then the terminal shows up some very large numbers.
That's because you use
static int n = 0;
then allocate memory for zero elements.
Change the line static int n = 256; for example, to allocate memory for 256 elements.
Or, if you read n after, allocate the memory AFTER you have read n. That is, declare the array globally first (technically a pointer), as int *arr;, then
arr = new int[n];
after cin >> n;
static is a much overloaded keyword.
The way you use it, it means translation-unit-local.
Also, you don't have any global array in your code, only a pointer initialized to point to the beginning of an allocation of 0 ints.
That allocation won't be changed if you later change n.

Storing array's of integers on the heap and accessing them via pointers

I'm hoping someone can shed some light on where I am going wrong with pointers.. I've read countless web pages and tried various things but for some reason my code is returning jibberish (which I'm guessing may be the memory addresses instead of the data within my array). The purpose of the program is to create an array of 100 elements on the heap, pass this array by a pointer to a function (along with two integer variables start and end); a new array will be created on the heap (this comprises of a chunk of the original array using the start and end variables) and the pointer to this array is passed back to the main method so that the new array can be outputted. My problem is not only is the output seeming to be the location not the value, but also it seems 100 values are outputted not 20 as should be expected. I've spent hours trying to figure out where I have gone wrong and just when I think I understand the concept of pointers my faith is destroyed by red squigglies and incorrect outputs. Please HELP! My code is as follows:
#include "stdafx.h"
#include <iostream>
#include <time.h>
using namespace std;
double* getSubArray(double*, int, int);// Declare a function that will get the sub array
int _tmain(int argc, _TCHAR* argv[])
{
const int size = 100;// Declare the size of the array
double* pA;// Declare the variable to hold the pointers to the data in array
double* pB;
int start = 15;
int end = 35;
pA = new double[size];// Create space for the array
srand(clock());// Seed the program to the computers current time so that random gets a different set of random numbers everytime it is run
// Use a for loop to traverse through each element of the array (starting at index 0) placing a number defined by the random function that is no higher than 250
for (int i = 0; i < size; i++)
{
pA[i] = rand()%250;
}
cout << "An Array of 100 numbers is created and stored in the heap, these values are:" << endl;
// Output the Array for the user to see
for (int j = 0; j < size; j++)
{
// Place 10 numbers on each line
if (j % 10 == 0)
{
cout << endl;
}
cout << *(pA + j) << " ";
}
cout << endl << "The program will build a second array using the data between the indexes " << start << " & " << end << endl;
pB = getSubArray(pA, start, end);// Pass the data to the method
// Output second array for user to compare
for (int k = 0; k < size; k++)
{
// Place 10 numbers on each line
if (k % 10 == 0)
{
cout << endl;
}
cout << *(pB + k) << " ";
}
system("pause");
return 0;
}
double* getSubArray(double* pA, int start, int end)
{
double* pB = new double[end-start];// Declare space in the heap for the new array whoes size is the size of the criteria given
for (int i = 0; i < (end - start); i++)
{
for (int j = start; j < end; j++)
{
*(pB + 0) = pA[j];
}
}
return pB;
}
*(pB + 0) = pA[j];
That keeps writing to the first element of the array. Surely you want to write to each element in turn:
for (int i = start; i < end; ++i) {
pB[i-start] = pA[i];
}
or if you don't want to write your own loop
std::copy(pA+start, pA+end, pB);
Don't forget to delete[] everything you new[] or, to save mucking around with low-level memory management, use std::vector to manage the dynamic arrays for you.

C++ segmentation fault while passing address values between functions

I am trying to write a simple C++ algorithm to solve sudoku. I am trying to pass address values between different functions but i get segmentation fault at runtime. (Needless to say, i am not quite experienced :))
The code does manage to pass the address of a[0] to main function and i can read values using pointers inside main. When i try to pass the address to solve function, it gives segmentation fault.
(Also as a secondary question, i can read values correctly in main, using cout << *(a+5) etc. correctly (commented out in main), but when i try to print all 81 values stored using a for loop, it gives out nonsense values (again, commented out in code). The code works with literals like *(a+3) or a[3], but does not when an int gets involved for(int i, whatever) cout << *(a+i);)
#include <iostream>
using namespace std;
int * get_input();
void solve(int *);
int main()
{
int * a;
a = get_input();
//cout << *a << " " << *(a+1) << " " << *(a+2) << " " << *(a+3) << " " << *(a+4);
//for (int i = 0 ; i < 81 ; i++) {if (i%9 == 0) cout << "\n"; cout << a[i] << " ";}
solve(a);
return(0);
}
int * get_input ()
{
int a[81];
getinput:
for (int i = 0 ; i < 81 ; i++) {a[i] = 0;}
for (int i = 0 ; i < 81 ; i++) {cin >> a[i];}
print:
for (int i = 0 ; i < 81 ; i++)
{
if (i%27 == 0){cout << "\n";}
if (i%9 == 0) {cout << "\n";}
if (i%3 == 0) {cout << " " << a[i];}
if (i%3 != 0) {cout << a[i];}
}
cout << "\n\nCheck:\n1- Fix\n2- Reset\n3- Confirm\n\n";
int check = 0;
cin >> check;
if (check == 1)
{
int input[3] = {-1, -1, -1};
while (true)
{
cin >> input[0] >> input[1] >> input [2];
if (input[1] == 0) goto print;
a[(input[2]-1)+((input[1]-1)*9)] = input[0];
}
}
if (check == 2) goto getinput;
if (check == 3) return a;
}
void solve(int * a)
{
bool matrix[9][9][9];
for (int i = 0 ; i < 81 ; i++) {for (int j = 0 ; j < 9 ; j++) {matrix[(i-i%9)/9][i%9][j] = true;}}
for (int i = 0 ; i < 81 ; i++)
{
if (a[i] == 0) continue;
else
{
for (int j = 0 ; j < 9 ; i++)
{
matrix[(i-i%9)/9][j][a[i]] = false;
matrix[j][i%9][a[i]] = false;
matrix[((i-i%9)/9)-((i-i%9)/9)%3+j%3][i%9-(i%9)%3+(j-j%3)/3][a[i]] = false;
}
}
}
for (int i = 0 ; i < 9 ; i++)
{
for (int j = 0 ; j < 9 ; j++)
{
cout << matrix[i][j][1] << " ";
}
cout << "\n";
}
}
You are returning an address to a local variable in getInput(the array a). I would suggest you pass the array as argument to this function. Another option is to allocate the array dynamically and then take care to free it before the program terminates.
Make the a array in your get_input() function static:
int a[81];
should be
static int a[81];
This works because the static keyword ensures that the allocated memory block (the array a ) will remain allocated after the function returns. Usually this is "because I'm not finished with it yet" (for example, you can count how many times your function is called this way), but it can also, legitimately, be used to ensure that the return value of a function survives the end of the function.
Marginally better would be to declare the array at the main level, and pass a pointer to it into the get_input() and solve() functions. That way you make it explicit in the code that the array will "live for the duration of the program" - and that's usually good practice.
int a[81];
This is a local memory allocation, and its freed when your function get_input returns.
Use a pointer int* a, and malloc function to allocate dynamically memory instead!
The malloc command may is like this(if i remember it well):
int *a = (int *) malloc(sizeof(int)*81);
You're problem is that you are returning a pointer to a locally declared variable. Don't do this. You should either pass in the variable as a parameter (eg. get_input(int[] arr, int length)` or allocate new memory on the heap for your array. The simplest is the former, the latter can get you into trouble as you have to manage your memory or you will get memory leaks.
Why do you need to do this? When you declare a[] in get_input it allocates the space for that variable on the stack. The stack is a long contiguous block of memory that is used to store a function's parameters, it's local variables and the address of the program that is calling the current function. When a function returns, all this memory is reclaimed for use by the next function call. That is, when solve is called it starts writing over the memory on the stack that was previously used by get_input.
You are quite lucky that you got a segmentation fault as it is sometimes possible for programs to continue operating even though their data has become utterly corrupted.
In summary: Declare your array in the main function and pass it to get_input to operate on.