C++ segmentation fault array - c++

In C++ I get a segmentation fault after telling the program how big the array should be (x).
Why is this happening and how do I fix this?
#include <iostream>
using namespace std;
int main()
{
int x;
cin >> x;
int array[x];
for (int *j=array; j; j++)
{
*j=0;
}
for (int *i=array; i; i++)
{
cin >> *i;
}
cout << array[3] << endl;
}

Your loop conditions are wrong.
for (int *j = array; j; j++)
and
for (int *i=array; i; i++)
will not stop at the end of the array, as the condition j (i) is true when traversing the array (i.e., to be false, the pointer needs to be nullptr). In fact, pointer arithmetic past the array boundary plus one results in undefined behaviour. Your stopping condition should be
i < array + x;
Moreover, variable length arrays are an extension and not support by the C++ standard. Use new[] instead to allocate memory, as #Joshua Byer pointed out.

int * array;
array= new int [x];
http://www.cplusplus.com/doc/tutorial/dynamic/

The conditions used in your loops are incorrect.
eg. for (int *j = array; j; j++) even though j will eventually reach the end of the array but will still never evaluate to false (allowing the loop to finish). On top of this it means you will iterate to past the end of the array and move into Undefined Behaviour, this is probably why you are seeing the segfault.
you either need to do the following (super gross solution!!!! also not C++ standard supported):
for (int i = 0, *j = array; i < x; i++, j++)
which will increment a counter and check the array at the same time as incrementing your pointer.
OR
USE VECTORS
std::vector is a much easier way to do what you are doing.
int arraySize;
cin >> arraySize;
std::vector<int> array(arraySize, 0);
for (int i=0; i < arraySize; i++)
{
cin >> array[i];
}
cout << array.at(3) << endl;
Here is a live example.

Within a for statement, the second expression should terminate the loop by evaluating to false. In this case however you never terminate the loop:
for (int *j=array; j; j++)
Instead do:
for (int *j=array; j < array + x; j++)
The expression array + x (by pointer arithmetic) means one element past the end of the array.
The above goes for both of the loops.

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.

C++ filling in array with input from another

I'm just taking input for two arrays and manipulating the information. When I take input for both arrays it puts the information from the second into both arrays. In the code below I haven even commented out the input for the second array to see what happens and it still puts the input for M into both arrays. Can anyone see the cause?
int M[0], N[0];
std::cin >> m >> n;
for (int i = 0; i < m; ++i)
{
std::cin >> M[i];
}
for(int i=0; i<m; i++)
{
std::cout << M[i];
}
std::cout << "\n";
for(int i=0; i<n; i++)
{
std::cout << N[i];
}
For starters these declarations
int M[0], N[0];
are invalid, You may not declare an array with zero elements.
Thus the code has undefined behavior.
Secondly variable length arrays are not a standard C++ feature. Either declare the arrays with the potentially maximum number of elements or use the standard container std::vector.
the code that you just showed has a problem.
You print only M because you didn't do the input for-loop for the N array. So the array N has nothing inside.
So to fix this do another for and ask for input in the array N.
for (int i = 0; i < m; ++i)
{
std::cin >> N[i];
}
Hope this helps.

Function behaves badly when passing dynamically allocated pointer

I have this function
void shuffle_array(int* array, const int size){
/* given an array of size size, this is going to randomly
* attribute a number from 0 to size-1 to each of the
* array's elements; the numbers don't repeat */
int i, j, r;
bool in_list;
for(i = 0; i < size; i++){
in_list = 0;
r = mt_lrand() % size; // my RNG function
for(j = 0; j < size; j++)
if(array[j] == r){
in_list = 1;
break;
}
if(!in_list)
array[i] = r;
else
i--;
}
}
When I call this function from
int array[FIXED_SIZE];
shuffle_array(array, FIXED_SIZE);
everything goes all right and I can check the shuffling was according to expected, in a reasonable amount of time -- after all, it's not that big of an array (< 1000 elements).
However, when I call the function from
int *array = new int[dynamic_size];
shuffle_array(array, dynamic_size);
[...]
delete array;
the function loops forever for no apparent reason. I have checked it with debugging tools, and I can't say tell where the failure would be (in part due to my algorithm's reliance on random numbers).
The thing is, it doesn't work... I have tried passing the array as int*& array, I have tried using std::vector<int>&, I have tried to use random_shuffle (but the result for the big project didn't please me).
Why does this behavior happen, and what can I do to solve it?
Your issue is that array is uninitialized in your first example. If you are using Visual Studio debug mode, Each entry in array will be set to all 0xCC (for "created"). This is masking your actual problem (see below).
When you use new int[dynamic_size] the array is initialized to zeros. This then causes your actual bug.
Your actual bug is that you are trying to add a new item only when your array doesn't already contain that item and you are looking through the entire array each time, however if your last element of your array is a valid value already (like 0), your loop will never terminate as it always finds 0 in the array and has already used up all of the other numbers.
To fix this, change your algorithm to only look at the values that you have put in to the array (i.e. up to i).
Change
for(j = 0; j < size; j++)
to
for(j = 0; j < i; j++)
I am going to guess that the problem lies with the way the array is initialized and the line:
r = mt_lrand() % size; // my RNG function
If the dynamically allocated array has been initialized to 0 for some reason, your code will always get stack when filling up the last number of the array.
I can think of the following two ways to overcome that:
You make sure that you initialize array with numbers greater than or equal to size.
int *array = new int[dynamic_size];
for ( int i = 0; i < dynnamic_size; ++i )
array[i] = size;
shuffle_array(array, dynamic_size);
You can allows the random numbers to be between 1 and size instead of between 0 and size-1 in the loop. As a second step, you can subtract 1 from each element of the array.
void shuffle_array(int* array, const int size){
int i, j, r;
bool in_list;
for(i = 0; i < size; i++){
in_list = 0;
// Make r to be betwen 1 and size
r = rand() % size + 1;
for(j = 0; j < size; j++)
if(array[j] == r){
in_list = 1;
break;
}
if(!in_list)
{
array[i] = r;
}
else
i--;
}
// Now decrement the elements of array by 1.
for(i = 0; i < size; i++){
--array[i];
// Debugging output
std::cout << "array[" << i << "] = " << array[i] << std::endl;
}
}
You are mixing C code with C++ memory allocation routines of new and delete. Instead stick to pure C and use malloc/free directly.
int *array = malloc(dynamic_size * sizeof(int));
shuffle_array(array, dynamic_size);
[...]
free(array);
On a side note, if you are allocating an array using the new[] operator in C++, use the equivalent delete[] operator to properly free up the memory. Read more here - http://www.cplusplus.com/reference/new/operator%20new[]/

C++ Code Output explanation

I have the following code, and the question asks me to find the output. I've found the output (2) by typing it in, but I'm having trouble figuring out how/why. Any Help?
Here's the code:
int scores[5];
int *numbers = scores;
for (int i=0; i <=4; i++)
*(numbers+i)=i;
cout << numbers[2] <<endl;
Your code essentially does
scores[2] = 2;
cout<<scores[2]<<endl;
Thus the answer..
In more detail:
int scores[5];
int *numbers = scores; //numbers points to the memory location of the array scores
for (int i=0; i <=4; i++) // as mentioned, stray ';'
*(numbers+i)=i; //same as numbers[i] = i which is same as scores[i] = i
cout << numbers[2] <<endl;
The only statement being executed by the for loop is
*(numbers+i)=i;
Which will store the index of the int element at that position using the deference operator (*).
Then you are printing out the THIRD number, which equates to 2, since arrays start at index 0.
You set a pointer to the first memory location of the array, then traverse the series of memory addresses and write to them. It should be noted that using pointer arithmetic with a dereference,
*(pointer + i) = i;
is the same as using the subscript operator:
pointer[i] = i;

An issue about c/c++ Segmentation fault

I wrote a simple program to test array pointer:
#include <iostream>
using namespace std;
int main(){
int (*array)[10];
int i, j;
for (i = 0; i < 10; i++){
for (j = 0; j < 10; j++)
array[i][j] = 1;
}
for (i = 0; i < 10; i++){
for (j = 0; j < 10; j++)
cout << array[i][j] << " ";
cout << endl;
}
return 0;
}
why the g++ "Segmentation fault"?
by the way, my os is ios x64.
Thanks
Chuan
array is a pointer to an array, which you apparently already know. However, you never allocated memory for the actual array, i.e. your pointer is pointing "nowhere". You are trying to access something that does not exist, which often leads to segmentation fault.
For example, you can declare an actual array
int array10x10[10][10];
and make your pointer point to it
array = array10x10;
(more precisely, your pointer is now pointing to the first 10-element subarray in array10x10). After that your code will work fine, meaning that by accessing array[i][j] you will indirectly access array10x10[i][j].
Alternatively you can allocate the actual array in dynamic memory, if you so desire
array = new int[10][10];
(just don't forget to do a delete[] array at the end).
You declare array as an array of pointers, then use it as an array of arrays.
You must declare it as multi-dimensional instead :
int array[10][10];