heap corruption after deleting dynamic array - c++

I know that this question was asked many times but I couldn't find the solution for my error
I am trying to make a program to check whether the matrix given is symmetric or not the user enters the number of test cases then the size then the matrix and the output is whether it's symmetric or not
the program works fine until I try a size more than 3 it breaks with this error and when debugging it seems that it breaks at delete[]arrL
#include <iostream>
#include <string>
using namespace std;
int n(char s)
{
switch (s)
{
case '0':
return 0;
case '1':
return 1;
case '2':
return 2;
case '3':
return 3;
case '4':
return 4;
case '5':
return 5;
case '6':
return 6;
case '7':
return 7;
case '8':
return 8;
case '9':
return 9;
}
}
int getnumber(string a)
{
string num = "";
for (int i = 0; i < a.size(); i++)
{
if (isdigit(a[i]))
num += a[i];
}
if (num.size() == 1)
{
return n(num[0]);
}
if (num.size() == 2)
{
return (n(num[0]) * 10) + (n(num[1]));
}
if (num.size() == 3)
{
return (n(num[0]) * 100) + (n(num[1]) * 10) + (n(num[2]));
}
}
bool matrix2(long int**p, int r)
{
int c = 0, u = 0, ss = 0;
for (int i = 0; i < r; i++)
{
for (int j = 0; j < r; j++)
{
if (p[i][j]<0)
return false;
}
}
long int*arrL = new long int[r];
long int*arrR = new long int[r];
for (int i = 0; i < r; i++)
{
for (int j = 0; j < i; j++)
{
arrL[c++] = p[i][j];
ss++;
}
}
for (int i = 0; i < r; i++)
{
for (int j = i + 1; j < r; j++)
{
arrR[u++] = p[i][j];
}
}
for (int i = 0; i < ss; i++)
{
int q = ss - i - 1;
long int a = arrR[i];
long int b = arrL[q];
if (!(a == b))
{
delete[]arrL;
delete[]arrR;
return false;
}
}
delete[]arrL;
delete[]arrR;
return true;
}
int main()
{
int t;
cin >> t;
for (int num = 0; num < t;num++)
{
int yy = num + 1;
string dimension;
cin.ignore();
getline(cin, dimension);
int r = getnumber(dimension);
long int**p = new long int*[r];
for (int w = 0; w < r; w++){
p[w] = new long int[r];
}
for (int w = 0; w < r; w++)
{
for (int ww = 0; ww < r; ww++)
{
cin >> p[w][ww];
}
}
bool result = matrix2(p, r);
if (result)
{
cout << "Test #" << yy << ": Symmetric." << endl;
}
else
{
cout << "Test #" << yy << ": Non-symmetric." << endl;
}
for (int i = 0; i < r; i++)
{
delete[]p[i];
}
delete[] p;
}
return 0;
}

arrL and arrR are allocated of size r, but then
arrL[c++] = p[i][j];
is executed more than r times, so c exceeds r, so you've corrupted your heap.

Related

How to fix signal SIGSEGV, Segmentation fault

I'm getting an error message in Codeblocks C++ 'Program received signal SIGSEGV, Segmentation fault' in comparison between a vector element and a size of vector of vectors inside for loop (line 133 if (parz_przestrzenie[i] != parz_dystanse[i].size())).
Could anyone tell me why?
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int bloki_parz[100000], bloki_nieparz[100000];
int silnia(int n)
{
int liczba = 1;
for (int i = 1; i <= n; i++)
{
liczba *= i;
}
return liczba;
}
int main()
{
int n, czapka, wolne_miejsca = 0, wynik = 1;
vector<int> parz, nieparz, parz_przestrzenie, nieparz_przestrzenie, parz_przestrzenie2, nieparz_przestrzenie2;
vector<vector<int>> parz_dystanse;
vector<vector<int>> nieparz_dystanse;
cin >> n;
for (int i = 1; i <= n; i++)
{
cin >> czapka;
if (i % 2 == 0)
{
parz.push_back(czapka);
}
else
{
nieparz.push_back(czapka);
}
}
int parz_size = parz.size(), nieparz_size = nieparz.size();
// sprawdzamy czy dane nie sÂą sprzeczne ; gdy zabraknie nam miejsc do rozmieszczania
vector<int> parz_duplicate = parz;
vector<int> nieparz_duplicate = nieparz;
parz_duplicate.erase(unique(parz_duplicate.begin(), parz_duplicate.end()), parz_duplicate.end());
nieparz_duplicate.erase(unique(nieparz_duplicate.begin(), nieparz_duplicate.end()), nieparz_duplicate.end());
int parz_dupl_size = parz_duplicate.size(), nieparz_dupl_size = nieparz_duplicate.size();
if (parz_size < nieparz_dupl_size)
{
cout << 0 << endl;
return 0;
}
if (nieparz_size < parz_dupl_size)
{
cout << 0 << endl;
return 0;
}
for (int i = 0; i < parz_size - 1; i++)
{
if (parz[i] == parz[i + 1])
{
bloki_parz[i + 1] = 1;
}
}
for (int i = 0; i < nieparz_size - 1; i++)
{
if (nieparz[i] == nieparz[i + 1])
{
bloki_nieparz[i] = 1;
}
}
for (int i = 0; i < parz_size; i++)
{
vector<int> bloczek;
for (int j = i; j < parz_size; j++)
{
if (parz[j] != parz[j + 1])
{
bloczek.push_back(parz[j]);
}
else
{
i += 1;
break;
}
}
if (bloczek.size() != 0)
{
parz_dystanse.push_back(bloczek);
}
}
int parz_dyst_size = parz_dystanse.size();
if (parz[parz_size - 1] != parz[parz_size - 2])
{
parz_dystanse[parz_dyst_size - 1].push_back(parz[parz_size - 1]);
}
for (int i = 0; i < nieparz_size; i++)
{
vector<int> bloczek;
for (int j = i; j < nieparz_size; j++)
{
if (nieparz[j] != nieparz[j + 1])
{
bloczek.push_back(nieparz[j]);
}
else
{
i += 1;
break;
}
}
if (bloczek.size() != 0)
{
nieparz_dystanse.push_back(bloczek);
}
}
int nieparz_dyst_size = nieparz_dystanse.size();
int current_wynik = 0;
for (int i = 0; i < nieparz_size; i++)
{
if (bloki_parz[i] == 0)
{
current_wynik++;
}
else
{
if (current_wynik != 0)
{
parz_przestrzenie.push_back(current_wynik);
}
current_wynik = 0;
}
}
parz_przestrzenie.push_back(current_wynik);
current_wynik = 0;
for (int i = 0; i < parz_size; i++)
{
if (bloki_nieparz[i] == 0)
{
current_wynik++;
}
else
{
if (current_wynik != 0)
{
nieparz_przestrzenie.push_back(current_wynik);
}
current_wynik = 0;
}
}
nieparz_przestrzenie.push_back(current_wynik);
int parz_przest_size = parz_przestrzenie.size(), nieparz_przest_size = nieparz_przestrzenie.size();
for (int i = 0; i < 1; i++)
{
if (parz_przestrzenie[i] != parz_dystanse[i].size())
{
wynik *= parz_przestrzenie[i];
wolne_miejsca++;
}
}
for (int i = 0; i < nieparz_przest_size; i++)
{
if (nieparz_przestrzenie[i] != nieparz_dystanse[i].size())
{
wynik *= nieparz_przestrzenie[i];
wolne_miejsca++;
}
}
cout << wynik * silnia(wolne_miejsca) << endl;
}
parz_dystanse is a vector of a vector. In this case the return value of parz_dystanse.size() is a long unsigned int, whereas an element of parz_przestrzenie is an int.
You need to make explicit that parz_dystanse.size() returns an int in order to make comparitions between integer expressions of different signedness.
This will fix that problem:
if (parz_przestrzenie[i] != (int)parz_dystanse[i].size())

compiling in linux using g++

I have following code which is simply tokenizing an array and then deviding on the basis of '<' and '>' characters. It is running fine in VS community 2019 but when I run it in Linux using g++ command it gives
Free(): invalid pointer
and
Aborted (core dumped)
errors. What am I doing wrong.
PS: error seems to be in the instructions where I am deallocating b in rangbrk and langbrk because when I put it in comments it runs fine in Linux too. But it runs fine in VS 2019 anyways.
//#include <sys/types.h>
//#include <sys/wait.h>
//#include <sys/stat.h>
#include <fcntl.h>
//#include <unistd.h>
#include<string.h>
#include<stdio.h>
#include<fstream>
#include<iostream>
#include<stdlib.h>
using namespace std;
//_________________________________________________________
int reads(char str[])
{//a simple function to get input
int s = 1;
char buffer[100];
cout << "enter command" << endl;
cin.getline(buffer, 100);
if (strlen(buffer) == 0)
{
cout << "Couldnt get input\n";
return 0;
}
for (int i = 0; i <= strlen(buffer); i++)
{
str[i] = buffer[i];
if (buffer[i] == 32)
s++;
}
return s;
}
//____________________________________________________________
int tokenizing(char** a, char str[], char buff[50], int x)
{//a function to devide a complete string into smaller parts
//also stores '/bin/command' into buff to pass as first parameter of execvp
int k = 0, m = 0;
bool check = false;
for (int i = 0; i < x; i++)
{
a[i] = new char[50];
for (int j = 0; str[k] != 32; j++)
{
if (str[k] == 0)
{
check = true;
break;
}
a[i][j] = str[k];
if (i == 0)
buff[j + 5] = str[k];
k++;
a[i][j + 1] = 0;
if (i == 0)
buff[j + 6] = 0;
}
m++;
k++;
if (check)
break;
}
return m;
}
//__________________________________________________________
void rangbrk(char**& a, char**& b, int& x, char filename[])
{//saperates the array before and after '>'
for (int i = 0; i < (x - 2); i++)
{
b[i] = new char[50];
for (int j = 0; j < 50; j++)
{
b[i][j] = a[i][j];
}
}
b[x - 2] = NULL;
for (int i = 0; i < 50; i++)
{
filename[i] = a[x - 1][i];
}
char** c;//temprory pointer to swap a and b
c = a;
a = b;
b = c;
x = x - 2;
for(int i=0;i<x-1;i++)
{
delete [] b[i];
}
b=NULL;
}
//__________________________________________________________
void langbrk(char** &a, char** &b, int& x, int index, char filename[])
{//saperates the array before and after '<'
int k = 0;
for (int i = 0; i < x; i++)
{
if ((i != index) && (i != index - 1))
{
b[k] = new char[50];
for (int j = 0; j < 50; j++)
{
b[k][j] = a[i][j];
}
k++;
}
}
b[x - 2] = NULL;
for (int i = 0; i < 50; i++)
{
filename[i] = a[index - 1][i];
}
char** c;//temprory pointer to swap a and b
c = a;
a = b;
b = c;
x = x - 2;
for(int i=0;i<x-1;i++)
{
if(b[i]!=NULL)
delete [] b[i];
}
b=NULL;
}
//__________________________________________________________
int main()
{
char buff[50] = { "/bin/" };
char str[100];
char exit[5] = { 'e','x','i','t',0 };
char outfile[50];
char infile[50];
int x = reads(str);
char** a;
a = new char* [x];
int s = tokenizing(a, str, buff, x);
a[s] = NULL;
bool flag = false;
for (int i = 0; a[i] != NULL; i++)
cout << a[i] << endl;
cout << s << endl;;
for (int i = 0; i < s; i++)
{
if (a[i][0] == '>')//checks if it need to print in a file
{
cout << i;
char** b;
b = new char* [s - 2];
rangbrk(a, b, s, outfile);
flag = true;
cout << "New" << endl;
for (int j = 0; j < s; j++)
cout << a[j] << endl;
i = 0;
}
else if (a[i][0] == '<')
{
cout << i;
char** c;
c = new char * [s - 2];
langbrk(a, c, s, i, infile);
cout << "New" << endl;
for (int j = 0; j < s; j++)
cout << a[j] << endl;
i = 0;
}
}
}
The reads function gets input, tokenizing tokenized the string in form of words. langbrk copies the string having index 1 less than index of '<' in infile and removes them both from main char** a. rangbrk removes '>' and string succeeding it from a and stores it in outfile

Magic Number output

Alright so I have created this code. However, when i run it, it stops when it displays 104 for the counter??? I am so frustrated because I don't know how this could happen. The purpose of the code is to do the typical magic number output where the rows all add up to the same thing, the columns all add up to the same thing, and the diaganols all add up to the same thing. I believe the functions to do these calculations are correct, but the counter keeps stopping short of the 10000 attempts I am trying to do.
#include <iostream>
#include<time.h>
#include<stdlib.h>
using namespace std;
void getrandom();
void insertnumber(int n);
bool magic();
void create();
const int rows = 3;
const int cols = 3;
int arr[rows][cols] = { {0,0,0}, {0,0,0} , {0,0,0} };
int main() {
int counter = 0;
do
{
counter++;
cout << counter << endl;
getrandom();
if (counter == 100000)
break;
} while (!magic());
create();
cout << "It took " << counter << " tries." << endl;
return 0;
}
void getrandom() {
int n = 0;
const int size = 9;
int oldnum[size];
for (int i = 0; i < rows * cols; i++) {
oldnum[i] = 0;
}
srand(time(NULL)); // had to import the new libraries to use this
bool used = true;
for (int i = 0; i < size; i++) {
do
{
used = true;
n = rand() % 9 + 1;
if (oldnum[n - 1] == 0)
{
oldnum[n - 1] = n;
used = false;
}
} while (used);
insertnumber(n);
}
}
void insertnumber(int n) {
for (int i = 0; i < rows; i++) {
for (int j = 0; i < cols; j++) {
if (arr[i][j] == 0) {
arr[i][j] = n;
return;
}
}
}
}
bool magic() {
int rowsum = arr[0][0] + arr[0][1] + arr[0][2];
for (int i = 1; i < cols; i++)
{
if (arr[i][0] + arr[i][1] + arr[i][2] != rowsum)
return false;
}
for (int j = 0; j < rows; j++)
{
if (arr[0][j] + arr[1][j] + arr[2][j] != rowsum)
return false;
}
if (arr[0][0] + arr[1][1] + arr[2][2] != rowsum)
return false;
if (arr[0][2] + arr[1][1] + arr[2][0] != rowsum)
return false;
return true;
}
void create() {
{
for (int i = 0; i < rows; i++) {
for (int j = 0; i < cols; j++) {
cout << arr[i][j] << " ";
}
cout << endl;
}
}
}
You can try using a debugger for such problems.
I think you code crashes because of this:
for (int i = 0; i < rows; i++) {
for (int j = 0; i < cols; j++) {
It looks like you mean j < cols here :)
Check line 76. When I compile and run the code, line 76 is where the exception is thrown.
This line specifically
arr[i][j] = n;
It seems your insertnumber() function is the culprit.

How to counting sort two dimensional array

Hi i have a problem with my code, i try sort array by counting sort (it must be stable sort), but my code doesn't work. I try implemented counting-sort from some wbesite, but it was in c# and I'm not sure s it done correctly. Can you tell me what is wrong with it?
#include <stdio.h>
#include <iostream>
using namespace std;
void sort_with_show(int **a, int rozmiar, int polecenie)
{
int y, d;
for (int i = 0; i< rozmiar - 1; i++)
{
for (int j = 0; j < rozmiar - 1 - i; j++)
{
if (a[j + 1][0] < a[j][0])
{
y = a[j][0];
a[j][0] = a[j + 1][0];
a[j + 1][0] = y;
}
}
}
for (int i = 0; i < rozmiar; i++)
{
//cout << tablica[i].x << " " << tablica[i].y << "\n";
if (polecenie == 0)
{
cout << a[i][0] << '\n';
}
else if (polecenie == 1)
{
cout << a[i][0] << "," << a[i][1] << "\n";
}
}
}
int main()
{
int rozmiar = 0;
int polecenie = 0;
char t[20] = { '\0' };
char *p, *q;
int liczba = 0;
int calaLiczba = 0;
bool isY = false;
cin >> rozmiar;
int ** a = new int *[rozmiar];
for (int i = 0; i < rozmiar; i++)
a[i] = new int[2];
cin.ignore();
int i = 0;
while(i < rozmiar)
{
fgets(t, sizeof t, stdin);
for (p = t, q = t + sizeof t; p < q; p++)
{
if (*p >= 48 && *p <= 57)
{
liczba = *p - 48;
calaLiczba = calaLiczba * 10 + liczba;
}
if (*p == ' ')
{
a[i][0] = calaLiczba;
isY = true;
calaLiczba = 0;
liczba = 0;
}
if (*p == '\n')
{
a[i][1] = calaLiczba;
isY = false;
}
}
for (int j = 0; j < 20; j++)
t[j] = '\0';
liczba = 0;
calaLiczba = 0;
isY = false;
i++;
}
cin >> polecenie;
cin.ignore();
sort_with_show(a, rozmiar, polecenie);
return 0;
}

Shouldn't this recursive method end as soon as you get to the return?

I would like to know why my output is:
a-b-b-b-b-0
When I think it should just be a-1.
Shouldn't a recursive method end as soon as you get to a return? and why doesn't it here?
I only put the letters with '-' to clarify that the returns are being met but not stopping there.
#include <stdio.h>
#include <iomanip>
#include <iostream>
using namespace std;
void printv(int mask[], int elements[], int n)
{
int i;
printf("{ ");
for (i = 0; i < n; i++)
if (mask[i])
printf("%d ", elements[i]);
printf("}");
}
int next(int mask[], int size)
{
int i;
for (i = 0; (i < size) && mask[i]; i++)
mask[i] = 0;
if (i < size) {
mask[i] = 1;
return 1;
}
return 0;
}
void nSubsets(int mask[], int elements[], int size, int n)
{
int sum = 0;
int temp[10], count = 0;
for (int i = 0; i < 10; i++) //this MUST be here
temp[i] = 0;
for (int i = 0; i < size; i++)
{
if (mask[i])
{
count++;
for (int k = 0; k < 44; k++)
if (temp[k] == 0)
{
temp[k] = elements[i];
sum += elements[i];
break;
}
}
}
if (sum == n)
{
cout << "{ ";
for (int l = 0; l < count; l++)
cout << temp[l] << " ";
cout << "}";
}
}
int isEmptySet(int mask[], int elements[], int size, int n, int sizeRecursion)
{
int sum = 0;
int temp[10], count = 0;
for (int i = 0; i < 10; i++) //this MUST be here
temp[i] = 0;
for (int i = 0; i < size; i++)
{
if (mask[i])
{
count++;
for (int k = 0; k < 44; k++)
if (temp[k] == 0)
{
temp[k] = elements[i];
sum += elements[i];
break;
}
}
}
if (sum == n)
{
cout << "a-";
return 1;
}
sizeRecursion--;
if (sizeRecursion > 0)
{
next(mask, size);
isEmptySet(mask, elements, size, n, sizeRecursion);
}
cout << "b-";
return 0;
}
int main()
{
int n, size = 10;
int elements[size];
size = 6; n = 5;
elements[0] = 5;
elements[1] = 2;
elements[2] = 3;
elements[3] = 2;
elements[4] = 1;
elements[5] = 1;
int mask[10];
int i;
for (i = 0; i < size; ++i)
mask[i] = 0;
cout << "Subsets of elements: ";
printv(mask, elements, size); //this prints first subset
while (next(mask, size))
printv(mask, elements, size);
n = 3;
cout << "\nSubsets equal to " << n << "\n";
while (next(mask, size))
nSubsets(mask, elements, size, n);
cout << "\n" << isEmptySet(mask, elements, size, n, size);
return 0;
}
Shouldn't a recursive method end as soon as you get to a return? and why doesn't it here?
No, the way it works in general is that when a function call returns, it only returns for that function call, and then the immediate caller may continue execution. It doesn't matter whether the function is recursive or not, each function call is separate and each call needs to hit a return statement at some point (unless the return type is void).
When you have this code
...
if(sizeRecursion > 0)
{
next(mask,size);
isEmptySet(mask, elements, size, n,sizeRecursion);
}
cout<<"b-";
return 0;
}
What's going to happen is, as soon as the recursive call to isEmptySet returns, its going to go right to the cout << "b-"; line and then to return 0;. If you don't want that then you should put those in an else block, and maybe also modify the line that calls isEmptySet so that it returns the value returned from that call.