segmentation fault in pointers while handling arrays - c++

I am trying to multiply array elements with 5 but I am getting the error of core dumped and if not, then, it only multiplies 5 with first element.
Here the code:
#include <iostream>
using namespace std;
int ptr_multiply(int[],int);
int main(){
int size;
cout<<"Enter the size of an array ==";
cin>>size;
int arr[size];
cout<<"Enter the elements of array ==";
for (int i=0;i<size;i++){
cin>>arr[i];
}
ptr_multiply(arr,size);
}
int ptr_multiply(int a1[],int s1){
int *ptr;
for (int i=0;s1;i++)
{
*ptr=a1[i];
ptr*=5;
cout<<"The Elements"<<" "<< i <<" "<<" after multiplying 5 is =="<<*ptr;
}}

*ptr=a1[i];
ptr*=5;
First line: You dereference a pointer that points nowhere (it is uninitialized). That is wrong and causes undefined behavior. You try to assign to an int when there is no int.
Second line: You do not dereference the pointer. You multiply the value of the pointer by 5 when you actually want to multiply the int it points to by 5 (remember: there is no int it points to).
You do not need a pointer here:
for (int i=0;i < s1;i++) {
int value = a1[i];
value *= 5;
cout<<"The Elements"<<" "<< i <<" "<<" after multiplying 5 is =="<<value;
}
Also the condition was wrong. It should be i < s1.
Last but not least, dont use C-arrays in C++. They are difficult to use and error-prone. Prefer std::array for fixed size arrays and std::vector for dynamic size. Actually int arr[size]; is not standard C++, see Why aren't variable-length arrays part of the C++ standard?

Related

Array size in C++ [duplicate]

This question already has answers here:
Accessing an array out of bounds gives no error, why?
(18 answers)
Closed 5 years ago.
I made a code in which I had to take the size of an array as the user’s input and its elements too and print them.
#include <iostream>
using namespace std;
//Compiler version g++ 6.3.0
int main()
{
int i;
cout<<"\nenter the size of array";
cin>>i;
int n[i];
for(int j=0;j<=i;j++)
{
cout<<"\nn["<<j<<"]=";
cin>>n[j];
}
for(int k=0;k<=i;k++)
{
cout<<endl;
cout<<"\nn["<<k<<"]=";
cout<<n[k];
}
}
Suppose in the following:
The value of i is 3 (according to user’s input).
In the first loop the condition for j is up to <=i where i is the size of array (this shouldn't happen as i begins from 0) due to which the Compiler asks me to input 4 values for the array (n[0], n[1], n[2] and n[3]) but the size of the array is 3 only. How can it store 4 objects?
Change this:
for(int j=0;j<=i;j++)
to this:
for(int j = 0; j < i ; j++)
since array indexing ends at the size of the array minus 1. In your case i - 1.
Likewise, you neeed for(int k=0;k<i;k++).
Your posted code invoked Undefined Behavior, by accessing the array out of bounds.
This:
int n[i];
is a Variable Length Array (VLA), which is not Standard C++, but is supported by some extensions.
and if you compiled with pedantic flag, you would get:
prog.cc: In function 'int main()':
prog.cc:9:9: warning: ISO C++ forbids variable length array 'n' [-Wvla]
int n[i];
^
If you want something like this data structure, then I suggest you use an std::vector instead, which is Standard C++.
By the way, it's not a syntax error or something, but i is usually used as a counter (like you used j), an index if you like. As a result, I would chnage it's name to size, for instance, or something related.
EDIT:
Example with std::vector and variable renaming:
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int tmp, n;
cout<<"Input number of elements\n";
cin >> n;
vector<int> v;
for(int i = 0; i < n; ++i)
{
cin >> tmp;
v.push_back(tmp);
}
for(auto number: v)
cout << number << endl;
return 0;
}
You need to check for less than i and not less than equal i. Otherwise it will try to store value for 0,1,2,3 in that case the last object will cause memory corruption. In c++ it will not give you any error even if you try to add 100 members in array of size 3.
It better you read memory management in c++ before jumping into coding.

Can passing an array of pointers to a function as an 'int' parameter convert the addresses to integers?

Beginner c++ programmer, writing code to solve Sudoku puzzles. I'll keep the background info short to avoid confusion.
I have an array of pointers, int *P[9], I have assigned each entry a specific address. I want to assign these addresses to another array of pointers, int *B[81].
P[0] should correspond to B[0], P[1] to B[8], and so on.
When I pass these to a function:
void (int B[ ], int P[ ] ) {...}
it seems like the function is converting the address P[ ] is pointing to into an integer value. Before the function is called P[0] points to the address 0x7fff978d46b0, if I check the value of P[0] inside the function it's a number like `48782346 .
#include<iostream>
using namespace std;
void assign_box(int matrix[], int P[])
{
cout << "P[0] in function: " << P[0] << "\n";
matrix[0]=P[0];
}
int main()
{
int table[9][9];
//Initialise table entries to 0
for(int i=0; i<9; i++)
{
for(int j=0; j<9; j++)
{
table[i][j]=0;
}
}
//Assign addresses to vector P, for brevity P is of length one
int *P[1];
P[0]=&table[0][0];
cout<< "P[0] before function: " << P[0] << "\n";
int*B[81];
assign_box(B[81], P[9]);
}
If it did this and worked I wouldn't care, but unfortunately when I assign B[0] = P[0], it hits me with a Segmentation fault (core dumped), which makes me wonder is the function trying to assign the pointer B[0] to the address 48782346.
Is it possible for the function to convert an address into an integer value?
Apologies if my question is unclear or verbose, first time asker. And thank you for edits.
If you dereference int*[] (or int**), you get an int*. If you dereference an int*, you get an int. This is exactly what you are doing, and why you end up with an int at the end.
//main
int *P[1]; //Array of pointers to int
int *B[81]; //Array of pointer to int
assign_box(B[81], P[9]); //Pass in two pointers to int
//assign_box
matrix[0]=P[0]; //assign int to int
You probably meant to call assign_box like assign_box(B, P), and have the signature be void assign_box(int *B[], int *P[]);. This would then allow you to assign one pointer inside an array to another pointer inside an array.
There are multiple things that could be causing segmentation faults, but they all stem from invalid array indices. If an array is declared like type identifier[size];, it has valid indices from 0 to size - 1. So, int *B[81]; means B[81] is invalid.
You're passing in the wrong parameters. You're trying to pass in an array object B[81] which does NOT EXIST. You only have B[0] - B[80]. Also, B[80] isn't an int pointer. It's an int within an int array. P[9] is a pointer to an array of integers. So, you're trying to pass an integer in an array slot that does not exist into a parameter that does not take integers -- it takes integer arrays.
#include<iostream>
using namespace std;
void assign_box(int matrix[], int P[])
{
cout << "P[0] in function: " << P[0] << "\n";
matrix[0]=P[0];
}
int main()
{
int table[9][9];
//Initialise table entries to 0
for(int i=0; i<9; i++)
{
for(int j=0; j<9; j++)
{
table[i][j]=0;
}
}
//Assign addresses to vector P, for brevity P is of length one
int *P[1];
P[0]=&table[0][0];
cout<< "P[0] before function: " << P[0] << "\n";
int*B[81];
assign_box(B[81], P[9]); // WRONG
}

linker error in C++ (again) [duplicate]

This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 7 years ago.
so I needing some help with creating a program for my class. The lab requires us to use pointers.
This is the description of what we have to do...
-Write a function that accepts an int array and the array's size as arguments.
-The program should ask the size of the array and lets the users enter some integer values.
-The function should create a new array that is one element larger than the argument array.
-The first element of the array should be set to 0.
-Element 0 of the argument array should be copied to element 1 of the new array.
-Element 1 of the argument array should be copied to element 2 of the new array, etc.
-The function should return a pointer to the new array.
-There should be three other functions: getMode, getMedian and getAverage.
-These functions should get Mode, Median and Average of the values within an array.
-You should display the argument array and the new array as well as the mode, median and the average.
This is what I have so far I'm not sure if its right. Any help is greatly appreciated.
UPDATE: I run the program and it asks the user for the size of the array and the values for it...
#include <iostream>
#include <cmath>
#include <cstdlib>
#include <string>
int* addToSize (int*, int);
using namespace std;
int main()
{
int userSize=0; //Holds user size
int userInts; //Holds uaer values
int *memory; //dynamically allocate an array
//int *intptr;
//int *arrayNew;
//int newA;
//Gets array size
cout << "Please enter the array size!" << endl;
cin >> userSize;
//Memory array
memory = new int [userSize];
//Grab values for the amount of user size
for (int count = 0; count < userSize; count ++)
{
cout << "Please enter the value for " << count+1 << endl;
cin >> userInts;
}
for (int index = 0; index < userSize; index ++)
{
cin >> memory[index];
}
//Sets addToSize function to memory array
memory = addToSize(memory, userSize);
//Shows memory array
for(int index=0;index< (userSize + 1);index++)
cout<<memory[index]<<endl;
delete[] memory; //Used to delete memory array
memory = 0; //sets memory array to 0
return 0;
}
int* addToSize(int* arrayNew, int newSize)
{
int* expandSize= new int [newSize +1];
for (int index = 0; index < newSize; index++)
{
expandSize[index]= arrayNew[index];
}
for (int index = newSize; index < (newSize+1); index ++)
{
expandSize[index]=0;
}
return expandSize;
}
You have declared a forward reference to some addToSize() function which accepts 2 arguments, and you proceed to invoke it from within your main(), and that's all very fine and dandy, but then further down you define an addToSize() which accepts 3 arguments.
So, what is happening is that the declared function is unrelated to the defined function. The compiler completely ignores the 3-argument function, since you are not calling it, and it assumes that you will provide a definition for the two-parameter function in some other source file.
But then when the linker attempts to link your program, there is no other file containing an addToSize() with two arguments, so the linker fails with an error message which describes precisely what happened. (It is a linker error. It has nothing to do with pointers and arrays.)
Hint: before fixing your function definition to match the declaration, lose the forward declaration, move the function to the start of the file, and make it static.

If we declare an array of four elements, can these elements store values?

In C++ if we declare an array of four elements, can these elements store values? I mean, if we declare the following array:
#include <iostream>
int main()
{
int a[4];
double res;
double avg;
avg = res = 0.0;
for(int i=0; i<4; i++)
{
cout<<"Please enter age ";
cin>> a[i];
}
for(int i=0; i<4; i++)
{
cout<< "You have entered these ages " <<a[i];
cout<<endl;
res += a[i];
}
avg = res/4;
cout<< "Total is "<<res <<endl;
cout<< "Avg is "<<avg;
}
this above program is a program with an integer (numeric) array, while in character array can we assign any value of the character array's elements?
Yes.
Array is a placeholder for the values of same type and no. of places are reserved during array declarion.
int a[3];
means it can store 3 ints. to be accessed as a[0], a[1] and a[2].
Now, you can see the problem you have in your loop:
for(int i=1; i<=4; i++)
{
cout<<"Please enter age ";
cin>> a[i];
}
a[0] remains empty
loop runs 4 times: a[1], a[2], a[3], a[4] and, last 2 indices are not reserved.
You can correct it as following:
for(int i=0; i<3; i++)
{
cout<<"Please enter age ";
cin>> a[i];
}
your other question:
while in character array can we assign any value of the character array's elements
Nope, Each index will store exactly one char.
char c[3];
will store exactly 3 chars. if you tried to use other indices it may result into undefined behaviour, segmentation fault. as you are trying to access memory that was not allocated to your process.
Yes, the declared elements are available to store values.
However, in your example you have only declared a 3-element array, which gives you array elements a[0], a[1], and a[2]. You are accessing array elements a[1], a[2], a[3], a[4], resulting in an out-of-bounds situation.
If you are asking whether it's possible to assign a value to an element of an array, then the answer is yes. All of the following is perfectly valid:
char a[10];
a[4] = 'x';
std::cin >> a[6];
Note however that your code contains errors:
You index a with indices 1 to 4. This means a must be at least 5 elements long; it's currently defined with length of 3.
#include <iostream.h> should be just #include <iostream>. <iostream.h> is pre-standard and obsolete.
C++ array indices are 0 based, so while not technically an error, you're ignoring the first element of your array. You should probably phrase your for loops as for (int i = 0; i < 4; ++i)

Passing a variable of type int[5][5] to a function that requires int**

I'd like to test a function that takes runtime-allocated multidimensional arrays, by passing it a hardcoded array.
The function has a signature of void generate_all_paths(int** maze, int size) and the array is defined as int arr[5][5] = {REMOVED}.
I'm not exactly sure how to properly coerce the array for the function (or if that is impossible).
This multi dimensional array topic unfortunately confuses so many C++ programmers. Well, here is the solution:
void generate_all_paths(int (*maze)[5], int size);
That is what the function declaration has to look like. An alternative, but fully equivalent is
void generate_all_paths(int maze[][5], int size);
Both are creating a parameter that is a pointer to an array of 5 integers. You can then pass your array of arrays of 5 integers to that function:
generate_all_paths(arr, 5);
Because your array's first element is an array of 5 integers, it will be converted automatically (implicitly) to a pointer to that first element when passed to that function.
In the comments, you have shown you are bound to an int**, because both your inner and outer dimension must have runtime values. A multi-dimensional array can not be used anymore. What you can do for testing purposes then is to create an array of pointers like this:
int store[5 * 5] = { ..... };
int *arr[5] = { store, store + 5, store + 10, store + 15, store + 20 };
Then, actually, you can have your function accept a int**. As the first element of you array then is a int*, it will be converted to a int** automatically. Another way of doing this is keeping the data in the 2 dimensional array, but just creating a "view" structured of pointers to that array:
int *arr[5] = { store[0], store[1], store[2], store[3], store[4] };
Where store is your int[5][5] array. Since store[n] accesses the n'th sub-array of that two-dimensional array and the element type of it is int, the pointer-converted type of it is int*, which will be compatible again.
You can write:
void display(char **a)
And then use a[i][j] to refer to elements in it.
The declaration char ** means "pointer to pointer to integer". To break it down into steps:
char *b = a[i];
That gets you a pointer to the first element of the i'th array in the array-of-arrays.
char c = b[j];
That gets you the j'th element in the array b.
The next problem you'll have is of allocating such an array-of-arrays.
char **arrayOfArrays = new char *[10];
for (int n = 0; n < 10; n++)
arrayOfArrays[n] = new char[20];
That allocates an array of 10 arrays, each "child" array having 20 characters.
In C/C++, array access syntax is just a way of retrieving a value some distance away from a pointer.
char *p = "Hello";
char *pl = p + 2; // get pointer to middle 'l'
char l = *pl; // fetch
char o = p[4]; // use array syntax instead
void display(char ** array)
should work. Also I don't think that it is a reserved word in standard C/C++.
And also, why is array a reserved word?
It isn't. You are probably using Visual Studio where it's displayed as a keyword due to its use in C++/CLI as a native managed type. However, this is irrelevant for C++ and Visual Studio is misleading in that regard.
As to your problem: You can simply pass a pointer-to-pointers-to-char and then pass your nested array directly (provided you are working with a dynamically allocated array):
void display(char** array) …
That said, your function assumes a fixed, known array length and some other details. Better would be to use a nested std::vector, or std::string (for instance). Using such existing data types makes your life much easier.
void display(std::vector<std::string> const& array) {
for (size_t i = 0; i < array.length(); ++i)
cout << array[i] << endl;
}
To take advantage of this, your calling code needs to be changed as well to use these data structures instead of plain C arrays on chars.
The Earwicker's answer is missing an important fact. What he is proposing is an array of arrays. For the first this wastes memory for the array of pointers ("char **arrayOfArrays = new char *[10]" is the creation point of this). For the second the array of chars may then not be a continuous block of memory, which is often a problem.
The only workaround in C++ is to create a one dimensional array and calculate the indexes when you need them.
char *b = new char[width*height];
then you can refer to element x,y (x is along width, y along height) like this
char c=b[width*y+x];
This may be however a bit slower than the solution above (measured on GCC 3.4.5), so if you are not interested in continuous memory (for example you always access the elements with [][], never by adding integer to a pointer and dereferencing it), then you should use the array af arrays. However, if you are interested in having the continuous memory, e.g. to pass it as initializer to an std::string object or to send it as a whole through a network, you should use the second one.
The best is to use pointers, but Borland C++ admits passing arrays as parameters for functions. Look at this code (includes: iostream and conio):
////////////////////////////////////////////
void ReceivedArray(char x[5]){
for (int i=0; i<5; i++ )
cout << x[i];
}
void main(){
char *x = new char[5];
for (int i=0; i<5; i++ )
x[i]='o';
ReceivedArray(x);
getchar();
}
///////////////////////////////////////////////////////////////
For passing 2D arrays (oops! some lines in spanish, sorry!):
(includes: iostream, stdlb, stdio and math)
/////////////////////////////////////////////////
using namespace std;
void ver(int x[][20]){
for(int i=0; i<15; i++) {
for(int j=0; j<20; j++) {
cout<< x[i][j] <<" "; }
cout << "\n"; }
}
void cambiar0(int x[][20]){ int n[255];
for (int i=255; i>=0; i--)
n[255-i]=i;
for(int i=0; i<15; i++)
for(int j=0; j<20; j++)
for(int k=0; k<255; k++)
if(x[i][j]==n[k]) {
x[i][j]=k; break; }
}
int main(int argc, char* argv[]){
int x[15][20]; char a;
for(int i=0; i<15; i++)
for(int j=0; j<20; j++)
x[i][j]=rand()%255;
cout << "¿desea ver la matriz? s/n ";
cin >> a;
if(a=='s') ver(x);
cambiar0(x);
cout << "\n\n";
cout << "¿desea ver la matriz? s/n ";
cin >> a;
if(a=='s') ver(x);
system("PAUSE"); return 0;
}
///////////////////////////////////
Hope this is what you meant.
arr is a pointer to the multi-dimesional array you have and is actually a pointer to an int. Now since your function accepts a pointer to an int pointer, you need to get the address of arr using: &arr and pass that to the function so that you will have this code:
To coerce the array: Pass &arr to the function.
To reference the array inside the func: *maze[x][y]