I have a little program:
#include <iostream>
using namespace std;
void inputArray(int*& p, int& n);
void print(int *p, int n);
int main() {
int size = 0;
int *arr;
inputArray(arr, size);
}
void inputArray(int*& p, int& n) {
int *q = new int[n]; int m = n;
for (int i = 0; i < n; ++i) q[i] = p[i];
cout << endl << "How many numbers to insert? "; cin >> n;
delete p;
p = new int[n + m];
for (int i = 0; i < m; ++i) p[i] = q[i];
for (int i = 0; i < n; ++i) cin >> p[i + m];
n += m;
}
The purpose of this program is to insert an array of integer. However, when I try to run the program with Code::Blocks on Ubuntu, it often says:
free(): invalid pointer: 0xb7646000 ***
after I input n.
However, when I remove delete p; , everything works well. However, I still want to know the problem. Can anyone tell what the problem is?
delete p;
You never allocated p, so when you try to free p, it can't.
It's like trying to access someone else's bank account, you may have the name, but you ain't allowed to free his money.
And - just for the rant- , try using more verbose variable names, it never hurts. Especially if you drunk-review your code in a year.
You are assigning elements from the array p
for (int i = 0; i < n; ++i) q[i] = p[i];
But p was never allocated or assigned any values
int *arr;
inputArray(arr, size); // Here "arr" is "p" within the function
This constitutes undefined behavior and will behave as such.
Related
We were writing a code in our university (learning about Object Oriented Program). We wrote this class and the issue is that, as per my understanding and our teacher the program should crash in the following condition, but in my case it doesn't.
The thing is this line is the culprit
DynamicArray d, f;
f = d;
according to him(rest of the code is attached), since when main ends, deconstructor deletes f and then goes for d, but since pointer was pointing to same mem location in both cases, now it should give error when it tries to delete it, since there is nothing there....but my compiler runs the code perfectly. I am using gcc compiler. Denconstructor at the end of class, rest is to fill dynamic array.
#include <iostream>
#include <ctime>
class DynamicArray{
private:
int *arr;
int size, cap; //cap is the physical size, size is number of elements
public:
DynamicArray(){
arr = nullptr;
size = cap = 0;
}
DynamicArray(int i){
cap = i;
size = 0;
arr = new int[cap];
}
void pushback(int j){
if(cap == 0){
arr = new int[cap];
arr[0] = j;
size++;
cap++;
}
else if(size < cap){
arr[size] = j;
size++;
}
else if(size == cap){
int *arr2 = new int[cap * 2];
int i;
cap *= 2;
for(i = 0; i < size; i++){
arr2[i] = arr[i];
}
arr2[i++] = j;
delete[] arr;
arr = arr2;
}
}
void print(){
for(int i = 0; i < size; i++)
std::cout << arr[i] << " ";
}
~DynamicArray(){
if(arr != nullptr)
delete[] arr;
}
};
int main(){
DynamicArray d, f;
srand(time(nullptr));
int n = rand() % 5;
for(int i = 0; i < n; i++){
d.pushback(rand() % 10);
}
f = d;
f.print();
std::cout << std::endl;
d.print();
return 0;
}
Your code causes so-called "undefined behaviour". Basically, that means anything can happen, including that nothing happens or that whatever happens isn't easily observable. For a more precise definition of "undefined behaviour", you'd have to check e.g. the C++ standard, but there are also many discussions concerning this term here.
Try running your code using e.g. valgrind, it will tell you that your code is broken.
I was doing a test and the online test engine showing segmentation error, which is confusing because with no further details, and I checked the pointer no NULL and they work pretty fine, but don't how array here works. Because when debugging, everything is fine, until I try to cout/print out the array. it's reporting a is crushed here and break. I can do nothing here if it break, and I hit break or continue. if I continue, it runs just fine. so I was really confused.
My computer is windows 7, I run code in visual studio 2010 c++.
Debugging is not that clear to solve the problem, and I am learning c++ not very efficient.
Solve with Array need dynamic allocation.
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
void reverseArray(int size, int num[]) {
if(size>1) {
int *p = &num[size-1];
int *f = num;
for(int i = 0;i < size/2; i++){
swap(*p, *f);
p--;
f++;
}
}
}
int main() {
int len;
int a[len];/This is the bug, can't use uninitialized var assign array/
cin >> len;
for(int i = 0; i < len; i++){
cin >> a[i];
}
reverseArray(len, a);
for(int i = 0; i < len; i++){
cout << a[i] << " ";
}
return 0;
}
This has something to with dynamic allocation, when I work in java, I create a new array.
I have to
int[] newArray = {2,4,1,2,3};
or
int[] newArray = new int[] {2,4,1,2,3};
Finally, this problem is solved, which makes me very happy.
Reading and learning is very important, coding is also important.
Thanks all,
And using vector instead of using array.
It would be easier.
#include <cstdio>
#include <vector>
#include <iostream>
using namespace std;
int main() {
int a;
int len;
vector<int> myvector;
cin >> len;
for(int i = 0; i < len; i++){
cin >> a;
myvector.push_back(a);
}
reverse(myvector.begin(), myvector.end());
for(int i = 0; i < len; i++){
cout << myvector[i] << " ";
}
return 0;
}
Using Array again(I doubt the following code):
#include<iostream>
//#include<cstdlib>
using namespace std;
void reverseArray(int size, int nums[]){
if(size > 1){
int *p = &nums[size-1];
int *q = nums;
for(int i = 0; i< size/2; i++){
swap(*p, *q);
p--;
q++;
}
}
}
int main(){
int len;
cin >> len;
int *a = new int[len];//a point to the first ele.
for(int i = 0; i< len; i++){
cin >> a[i];
}
reverseArray(len, a);
for(int i = 0; i < len; i++){
cout << a[i] << " ";
}
delete [] a;
return 0;
}
It worked perfect on my laptop, which is confusing because a is pointer, but I use it like an array. It shouldn't be working......
Final Array version:
http://ideone.com/ZMsD35
Done perfectly.
#include<iostream>
using namespace std;
int main(){
int len;
cin >> len;
int *a = new int[len];
for(int i = 0; i< len; i++){
cin >> a[i];
}
reverse(a, a+len);
for(int i = 0; i< len; i++){
cout << a[i];
}
delete [] a;
system("pause");
return 0;
}
The most likely reason for a segfault is the input. When the testing software passes len of size sufficient to overflow the automatic storage area, your program crashes on this line:
int a[len];
The exact value of len is system-dependent, but an input of 1,000,000 should do it on most common systems.
The fix is really straightforward - replace the declaration with
int a* = new int[len];
This will place the data in dynamic memory, rather than the automatic memory. It will also make your program standard-compliant, because variable-length arrays in C++ are an extension to standards.
Don't forget to delete a once you are done to avoid memory leak:
delete[] a;
So I've written a script for an assignment that does some matrix calculations. The input data consist of A(N x N), B(N x M) and pi(1 x N) matrices. All the testcases I am given give the correct results when the script is run. However when going though the assignment checker it gives me the following error:
Signal 11 is SIGSEGV, Segmentation Violation. This means that your
program has tried to access memory which it was not allowed to access,
either because the memory was not mapped by the process or due to
permission errors. Make sure everything is properly initialized, be
careful with your pointer arithmetic and don't follow null pointers.
I also googled (http://www.cyberciti.biz/tips/segmentation-fault-on-linux-unix.html), which told me that this error usually occur when i try to access memory which is not allowed. I however don't think this is the case here because i have all the calculations inside if-statements that check if the dimensions are faulty.
Does anyone know what this kind of error means, how to debug this kind of problems, and how to check against this? It's really hard to find since it compiles correctly and the calculations against the check cases are correct.
#include <iostream>
#include <fstream> // fstream
#include <sstream> // stringstream
using namespace std;
double **matCalc(double **A, double **B, int m, int n, int p, int q);
int main(){
std::istream &infile = std::cin;
if(infile){
std::string A_str;
std::string B_str;
std::string pi_str;
getline(infile, A_str);
getline(infile, B_str);
getline(infile, pi_str);
std::stringstream A_obj(A_str);
std::stringstream B_obj(B_str);
std::stringstream pi_obj(pi_str);
int m,n; // A
int p,q; // B
int r,s; // pi
int i,j,t; // iterators
A_obj >> m >> n;
B_obj >> p >> q;
pi_obj >> r >> s;
// Fill A
double **A = new double *[m];
for (i = 0; i < m; ++i){
A[i] = new double[n];
}
for (i = 0; i < m; ++i){
for (j = 0; j < n; ++j){
A_obj >> A[i][j];
}
}
// Fill B
double **B = new double *[p];
for (i = 0; i < p; ++i){
B[i] = new double[q];
}
for (i = 0; i < p; ++i){
for (j = 0; j < q; ++j){
B_obj >> B[i][j];
}
}
// Fill pi
double **pi = new double *[r];
for (i = 0; i < s; ++i){
pi[i] = new double[s];
}
for (i = 0; i < r; ++i){
for (j = 0; j < s; ++j){
pi_obj >> pi[i][j];
}
}
if (s == m){
double **CE = matCalc(pi, A, r, s, m, n);
int CE_row = r;
int CE_col = n;
if (CE_col == p){
double **EPD = matCalc(CE, B, CE_row, CE_col, p, q);
int EPD_row = CE_row;
int EPD_col = q;
cout << EPD_row << " " << EPD_col << " ";
for (i = 0; i < EPD_row; ++i){
for(j = 0; j < EPD_col; ++j){
cout << EPD[i][j] << " ";
}
}
}
else{cout << "Dim. Error" << endl;}
}
else{cout << "Dim. Error" << endl;}
}
return 0;
}
double **matCalc(double **A, double **B, int m, int n, int p, int q){
if (n==p){
int i,j,k;
double **c = new double *[m];
for (i = 0; i < m; ++i){
c[i] = new double[q];
}
for (i = 0;i < m; ++i){
for (j = 0;j < q; ++j){
c[i][j] = 0;
for (k = 0; k < n; ++k){
c[i][j] = c[i][j] + (A[i][k] * B[k][j]);
}
}
}
return c;
}
else{
double **c = 0;
cout << "Dim. Error" << endl;
return c;
}
//return c;
}
In particular - This section writes the answer which is checked against.
if (s == m){
double **CE = matCalc(pi, A, r, s, m, n);
int CE_row = r;
int CE_col = n;
if (CE_col == p){
double **EPD = matCalc(CE, B, CE_row, CE_col, p, q);
int EPD_row = CE_row;
int EPD_col = q;
cout << EPD_row << " " << EPD_col << " ";
for (i = 0; i < EPD_row; ++i){
for(j = 0; j < EPD_col; ++j){
cout << EPD[i][j] << " ";
}
}
}
else{cout << "Dim. Error" << endl;}
}
else{cout << "Dim. Error" << endl;}
double **pi = new double *[r];
for (i = 0; i < s; ++i){
pi[i] = new double[s];
}
Here you have allocated r double *s but iterated over i=0;i<s . This can be a potential problem. Therefore, carefully check variable ranges, lifetime of allocated memory.
Also, in double **EPD = matCalc(CE, B, CE_row, CE_col, p, q); CE, can be NULL from the previously returned value from matCalc call. There is no check if the return value was NULL OR, you do not have any check for illegal pointer dereferences within the function matCalc, which I will highly recommend.
Also, instead of passing pointer to a pointer, you might want to wrap the matrix into a class (or a struct), and define operations, like allocate and free. Possibly use smart pointers and stay safe.
In general, you can use debugger, like gdb and valgrind
Also, even it compiles properly, use the -Wall or both the -Wall -Wextra to see the warnings.
I would like to extend on #phoxis answer:
If you can reliably reproduce the error running the program under GDB and evaluating the stack is probably easiest.
Sometimes however, the bug might only manifest under certain circumstances or even worse you have a race condition in a multithreaded program and the segfault only happens once in a dozen runs.
This is why I would generally recommend to enable core dumps for your development and testing machines. In this case the kernel will write a dump of your program from the moment it tried to access memory it was not allowed to do. The good thing now is that you can load this core with GDB, e.g:
gdb -c <your-core-file>
You then can get the stacktrace of what happened with
> bt
Or in case of a multi threaded program you can get stack traces for all threads with:
> thread apply all bt
#include<stdio.h>
#include<stdlib.h>
int* getEvenNumbers(int arr[], int N)
{
int i, k = 0 , a[50], p;
for (i = 0; i < N; i++)
{
if (arr[i] % 2 == 0)
{
arr[k]=arr[i];
k++;
}
}
return arr[k];
}
int main ()
{
int i, arr[5000000], N, a[500000], k, *p;
printf("\nEnter your desired length of the array:\n\n");
scanf("%d", &N);
for (i = 0; i < N; i++)
arr[i]= rand();
getEvenNumbers (arr, N);
printf("\n\nEven numbers in the array are as follows:\n\n");
for (i = 0; i < N; i++)
{
a[i]= *(p+i);
printf("\n[%d] = %d", (i+1), a[i]);
}
}
please i know this is probably very easy for you guys but i need help figuring out how to return a pointer to the array without all my values of my array getting deleted, also i can't use global variables and it has to be a function that returns a pointer pointing to the array
First of all, decrease the size of those arrays, you don't need that much space. Second of all, you made your
getEvenNumbers
function return an int *, and not an int. arr[k] is not an int *. I also don't get why you are returning something if nothing is being assigned when you call the function. You can just change the return type to void.
void getEvenNumbers(int arr[], int N)
You also never allocate any memory for p. You can do
p = (int*) malloc(sizeof(int));
And since you never allocated any memory for p, the following line of code
a[i]= *(p+i);
is assigning a[i] to a random address. You should just try to rewrite this program. There a lot of errors in this program that I didn't even correct. Go on Google an look up finding even numbers in array program or something similar and look at the code of those examples.
EDIT:
I found some code examples for you to use. I hope it helps!
StackOverflow
sanfoundry.com
The caller already knows the address of the array, so you just need to return the new length. If we also remove the unused variables and take advantage of C++ declarations, we will have:
int getEvenNumbers(int* arr, int N)
{
for (int i = 0, k = 0; i < N; i++) {
if (arr[i] & 1 == 0) { // even if lowest bit is zero
arr[k] = arr[i];
k++;
}
}
return k;
}
Now you can print the even numbers easily:
int k = getEvenNumbers(arr, N);
printf("\n\nEven numbers in the array are as follows:\n\n");
for (i = 0; i < k; i++) {
printf("\n[%d] = %d", (i+1), arr[i]);
}
Dynamically allocate memory from heap.
int* a= new int [N];
//Now store the elements from index 1.
// at a[0] store the number of even number you have found in this function.
return a;
In main you know how many even numbers are there.
int *a1=getEvenNumbers(arr,n);
count_even=a1[0];
for(index=1;index<=count_even;index++)
cout<<a1[index];
The code is given here-
#include<stdio.h>
#include<stdlib.h>
int* getEvenNumbers(int arr[], int N)
{
int i, k = 1 , p;
int* a=new int[N+1];
for (i = 0; i < N; i++)
{
if (arr[i] % 2 == 0)
a[k++]=arr[i];
}
a[0]=k-1;
return a;
}
int main ()
{
int i, N;
printf("\nEnter your desired length of the array:\n\n");
scanf("%d", &N);
int arr[N];
for (i = 0; i < N; i++)
arr[i]= rand();
int *a=getEvenNumbers (arr, N);
printf("\n\nEven numbers in the array are as follows:\n\n");
for (i = 1; i <= a[0]; i++)
printf("\n[%d] = %d", (i), a[i]);
delete []a;
}
A better option is to use std::vector.You can read it here.
Let it be a create function for a dynamical allocated array:
void create(int *&a, int dim){
a=new int[dim];
for(int i=0;i<dim;i++){
a[i]=i+1;
}
Here, I need reference (&).
Now, I have a create function for a dynamical allocated matrix:
void create(int **&a,/* int**a, */ int lines,int rows){
...
}
I saw that reference is optional for dynamical allocated matrix create function. Why?
You need reference if you want to allocate the "outer" array - lines. Without it, you can allocate only "inner" arrays - rows (if "outer" array has been already allocated). So in your case, reference is mandatory.
void create(int **a, int lines, int rows)
{
a = new int*[lines]; // passed pointer to 'a' will point to an old address
for(int i = 0; i < lines; i++)
a[i] = new int[rows];
}
If you want to modify the pointer passed to a function inside the function, it needs to be passed by reference.
So no, the reference is not optional in your case. Wherever you saw that it's optional, was wrong.
My bad. I'm sorry.
I saw that refference in assignValues function isn't necessary so I thought that it is unnecessary for the create function, too.
Thank you all for replies.
Again, I'm sorry.
Here is my code:
#include <iostream>
#include <conio.h>
using namespace std;
void create(int **&a, int lines, int rows){
int i;
a = new int*[lines];
for (i = 0; i < lines; i++){
a[i] = new int[rows];
}
}
void assignValues(int **a, int lines, int rows){
int i,j,k = 1;
for (i = 0; i < lines; i++){
for (j = 0; j < rows; j++){
a[i][j] = k;
k++;
}
}
}
void print(int **a, int lines, int rows){
int i, j;
cout << "Matrix is: "<<endl;
for (i = 0; i < lines; i++){
for (j = 0; j < rows; j++){
printf("%3d",a[i][j]);
}
cout << endl;
}
}
int main()
{
int lines = 5;
int rows = 4;
int **a = 0;
create(a, lines, rows);
assignValues(a, lines, rows);
print(a, lines,rows);
_getch();
return 0;
}