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.
Related
For this assignment, I need to make a sorted copy of an array the user has given values to. All of my code works as intended, except for this specific part. I need this function (sortedCopy) to print out the sorted version of their array, without actually changing the array itself. As far as I can tell, to do so I need to used a constant version of the array in the function so the prototype would be something like: int *sortedCopy(const int *array, int size), but all this does is give the error shown in the title. Specifically:
main.cpp:72:29: error: assignment of read-only location '*(array +
((sizetype)(((long unsigned int)i) * 4)))' array[i] = array[min]
and it does this error twice, except with array[min] = temp; at the end instead
This is the code used, with the relevant parts of main:
#include <iostream>
using namespace std;
int* sortedCopy(const int *array, int size) {
int i, j, min, temp;
for (i = 0 ; i < size - 1; i++) {
min = i;
for (j = i + 1; j < size; j++) {
if (array[j] < array[min]) {
min = j;
}
}
temp = array[i];
array[i] = array[min];
array[min] = temp;
}
cout << "Sorted array is: " << endl;
for(int i = 0; i < size; i++) {
cout << array[i] << " ";
}
cout << endl;
// Not sure if I need to return anything or not either
}
int main() {
cout << "Please enter the size of the array." << endl;
int arraySize;
int array[arraySize];
cin >> arraySize;
cout << "Please enter integer values until the array is filled." << endl;
for (int i = 0; i != arraySize; i++) {
cout << "Value " << (i + 1) << ": ";
cin >> array[i];
cout << endl;
sortedCopy(array, arraySize);
for (int i = 0; i != arraySize; i++) { // I want this part to print the
cout << array[i] << " "; // original array entered by the user
}
}
If I remove the const part of the function, it works totally fine, except it will print the sorted array after the function is called, instead of the original array.
Firstly, C/C++ is best read "top-down":
int arraySize;
int array[arraySize]; // arraySize is undefined here!!
cin >> arraySize;
On the second line, ArraySize, might be 1, or 0, or -1000. You haven't defined it until line 3.
Also, C++ doesn't allow you to allocate arrays of variable size (unless that size is const [ so it is known at compilation time]):
int array[4];
The above is fine. This helps the operating system know how much memory to provide for you on the stack (it needs to do this before your programme starts running).
const int arraySize = 4;
int array[arraySize];
Because the C++ compiler knows that arraySize is 4, it processes this just like the above code, so this is also fine.
So to handle arrays of genuinely variable length (length that depends on inputs), you need to first read the user inputs, then use dynamic allocation ("new", or a container that does dynamic allocation for you, like a vector).
As for the problem with "const", what I think that you need to understand here is that "const" is really just a promise from the programmer: The programmer is communicating to the compiler (and any programmers reading the code) that this data is not supposed to change. All the compiler does is check whether you keep your promise (or if you send it to another function / pointer that doesn't hold that promise). So by using "const" there is no work done being done for you to actually keep the data constant - just that it will complain if you don't do the work.
int* sortedCopy(const int *array, int size) {
Above you're flagging to the compiler that the sortedCopy function will keep the data in the array constant.
array[i] = array[min];
array[min] = temp;
And here (above) you are breaking that promise.
If you don't want to edit the original array, then the easiest solution is just to copy it before you send it to your sorting function.
So This Is What I Ended up coming up with for it. I currently can't figure out how to put my reverseArray function into the main... If i just copy and paste the code into it, it crashes every time it's run... I don't know why it causes it to crash or anything. Thank you everyone that has helped me so far with this.
using namespace std;
// Prototype for printArray goes here
void reverseArray(int*, int);
void printArray(int*, int);
int main()
{
int size; // size of the dynamically allocated array
// Declare as needed for a dynamically allocated array of
ints named "data".
// Declare other variables as needed
// Edit to display your own name
cout << "" << endl << endl;
// Prompt the user for the array size
cout << "Array size: ";
cin >> size;
// Add code to validate array size, so it is greater than one
while (size < 2)
{
cout << "Array size must be greater than 1: ";
cin >> size;
}
// Add code to dynamically allocate "data". Don't forget to release the memory before
// the program ends
int *data = new int[size],
*p = data;
// Write a loop to fill the "data" array with random numbers from 1 - 100 (inclusive)
// This code must use POINTER NOTATION (no subscripting) to work with the array.
// Reminder: neither of these notations is acceptable here:
// data[n] or *(data + n)
// Instead this code will use pointer incrementing/decrementing and dereferencing
for (int i = 0; i < size; i++, p++)
{
*p = rand() % 100 + 1;
}
// Call function to print the original "data" array
cout << "\nOriginal array:\n" << endl;
printArray(data, size);
// Reset "data" to point to the beginning of the array
// Add code to reverse the array. Use 2 pointers: one starts at the beginning of the array and
// moves forward, the other starts at its last element and works backward. Swap the values they
// point to.
// Reminder: neither of these notations is acceptable here:
// data[n] or *(data + n)
// Instead this code will use pointer incrementing/decrementing and dereferencing
// For this, I made the function reverseArray instead of coding it in main.
reverseArray(data, size);
cout << endl;
cout << "\nReversed array:\n" << endl;
printArray(data, size);
cout << endl << endl;
// Finish up
delete[] data;
system("pause");
return 0;
}
// Function printArray() goes here. Print the array, 5 numbers per line,
right-aligned
void printArray(int*p, int size)
{
for (int i = 0; i < size; i++, p++)
{
cout << setw(5) << right << *p;
if ((i + 1) % 5 == 0)
{
cout << endl;
}
}
}
// Function reverseArray() Reverses the array.
void reverseArray(int *data, int size)
{
int *e = data + size - 1; // Pointer at the end
for (; e > data; data++, e--) // while end pointer (e)> start pointer, swap start w/ end
{
int arrayFlip = *data;
*data = *e;
*e = arrayFlip;
}
}
You may be torturing yourself for no reason, or beating your head into a brick wall (don't worry - we've all been there... and have the bruises to prove it.)
First, lets start with any allocated block of memory, say:
int *a = new int[NELEM], ...
What is a? (a pointer -- yes, but to what?) It is a pointer to the beginning address in a block of memory, NELEM * sizeof *a bytes in size. What type of pointer is it? (int). How many bytes per-int? (generally 4).
So why is having the pointer be type int important? (well, it sets the type-size that controls how pointer-arithmetic operates when referencing the block of memory though that pointer) Meaning since your pointer type is int, the compiler knows that a + 1 is a + 4-bytes which allows you to reference the next value in your block of memory.
OK, but I allocated memory for a, what are my responsibilities with regard to a? In any code you write that dynamically allocates memory, you have 2 responsibilities regarding any block of memory allocated: (1) always preserve a pointer to the starting address for the block of memory so, (2) it can be freed when it is no longer needed.
What does that mean to me? It means that if you cannot simply increment a (e.g. a++) in the scope where a was declared. If you do, you have lost your reference to the beginning address of the block and that block can no longer be freed (that's a memory leak).
So if I cannot use any indexing (e.g. a[i] or *(a + i)) and I can't increment my pointer a -- then what are my options? Use another pointer..., e.g.
int *a = new int[NELEM],
*p = a;
...
std::cout << "array : ";
for (int i = 0; i < NELEM; i++, p++) {
*p = rand() % 100 + 1;
std::cout << std::setw(5) << *p;
}
std::cout << '\n';
Have you satisfied your responsibilities regarding the block of memory you assigned to a? Sure, a still points to the beginning address of the block, so it can be freed. All you did was use a second pointer p and iterated using p leaving a unchanged.
Hmm.. Using a second pointer.. I wonder if I can reverse my array using that same scheme. Yep. In it simplest form, you could do something like:
void rev (int *a, size_t size)
{
int *e = a + size - 1; /* end pointer */
for (; e > a; a++, e--) { /* while end > start, swap start, end */
int tmp = *a;
*a = *e;
*e = tmp;
}
}
But wait!! You said you couldn't increment a without losing the starting address to my allocated block -- how can I free it now? (a in main() never changes, the function rev receives a copy of a and within rev you are free to increment/decrement or do whatever you like to a, within the bounds of the block of memory, because a in rev has its very own (and very different) address from your original pointer in main().
(an aside...) You could have declared a third pointer within rev, e.g.
int *s = a, /* start pointer */
*e = a + size - 1; /* end pointer */
and then used s instead of a in your iteration and swap, but there isn't any need to. You are free to do it that way if it is more clear to you which pointer you are working with. It's simply another 8-bytes (or 4 on x86), so the additional storage is a non-issue.
Putting it altogether in a short example, you could do something similar to the following:
#include <iostream>
#include <iomanip>
#include <cstdlib>
#define NELEM 10
void rev (int *a, size_t size)
{
int *e = a + size - 1; /* end pointer */
for (; e > a; a++, e--) { /* while end > start, swap start, end */
int tmp = *a;
*a = *e;
*e = tmp;
}
}
int main (void) {
int *a = new int[NELEM],
*p = a;
srand (20180502);
std::cout << "array : ";
for (int i = 0; i < NELEM; i++, p++) {
*p = rand() % 100 + 1;
std::cout << std::setw(5) << *p;
}
std::cout << '\n';
rev (a, NELEM);
p = a;
std::cout << "reverse: ";
for (int i = 0; i < NELEM; i++, p++)
std::cout << std::setw(5) << *p;
std::cout << '\n';
delete[] a;
}
Example Use/Output
$ ./bin/array_reverse
array : 11 6 78 93 25 71 82 58 97 68
reverse: 68 97 58 82 71 25 93 78 6 11
All of this takes a bit of time to sink in. We all have bruises on our foreheads from the same wall. Just make peace with the fact that a pointer is just a variable that holds the address of something else as it value (e.g. it points to where something else is stored).
Understand how the type of the pointer effects the pointer-arithmetic (and indexing), e.g. how many bytes are advanced with p++ or in for (i = 0; i < size; i++) p[i], and make sure you know exactly where your pointer is pointing and things should start to fall into place.
If you ever have any problems figuring out what is going on with your pointer, pull out an 8.5 x 11 sheet of paper and a No.2 pencil and just draw it out -- on each iteration fill in the block where your pointer is pointing, etc.. -- it really helps. Once you have drawn enough diagrams, done enough linked-lists, stacks, etc... you won't need the paper as much as you do now (you will still need it -- so keep it handy)
Reversing in main() with a Function
In response to your comment, when you look at main(), you already have an additional pointer p declared. So you can simply use that as your start pointer and add e from from the rev() function as your end-pointer. A simple implementation would be:
int main (void) {
int *a = new int[NELEM],
*p = a,
*e = a + NELEM - 1;;
srand (20180502);
std::cout << "array : ";
for (int i = 0; i < NELEM; i++, p++) {
*p = rand() % 100 + 1;
std::cout << std::setw(5) << *p;
}
std::cout << '\n';
p = a; /* reset pointer */
for (; e > p; p++, e--) { /* reverse array */
int tmp = *p;
*p = *e;
*e = tmp;
}
p = a; /* reset pointer -- again */
std::cout << "reverse: ";
for (int i = 0; i < NELEM; i++, p++)
std::cout << std::setw(5) << *p;
std::cout << '\n';
delete[] a;
}
(same output)
Look things over and let me know if you have further questions.
The following lines in main are not correct.
*data = rand() % 100 + 1;
cout << setw(5) << right << *data;
They just set the value of the first element of the array and print the same element.
Use data[i] instead.
data[i] = rand() % 100 + 1;
cout << setw(5) << right << data[i];
If you must use the pointer notation, use *(data+i).
*(data+i) = rand() % 100 + 1;
cout << setw(5) << right << *(data+i);
Another method you can use is to use a temporary pointer variable just for iterating over the array.
int* iter = data;
for (int i = 0; i < size; i++. ++iter)
{
*iter = rand() % 100 + 1;
cout << setw(5) << right << *iter;
...
}
This makes sure that you don't lose the original pointer, which is necessary to be able to deallocate the memory.
PS There may be other errors, or not, but I noticed the above problem after a quick glance through your code.
Moving A Pointer
data++;
and
data--;
mostly. There are other things you could do, but your instructor asked for increment and decrement.
So
for (int i = 0; i < size; i++)
{
*data = rand() % 100 + 1;
cout << setw(5) << right << *data;
if ((i + 1) % 5 == 0)
{
cout << endl;
}
}
becomes
for (int i = 0; i < size; i++)
{
*data = rand() % 100 + 1;
cout << setw(5) << right << *data++; // change made here
if ((i + 1) % 5 == 0)
{
cout << endl;
}
}
Note only one data++, and it's on the second use of data. You should be able to figure out why.
Resetting A Pointer
The easiest and most obvious is to
int*reset = data;
then you can data around to your heart's content, and when you want to reset,
data = reset;
So the above loops wind up looking like
int*reset = data;
for (int i = 0; i < size; i++)
{
*data = rand() % 100 + 1;
cout << setw(5) << right << *data++; // change made here
if ((i + 1) % 5 == 0)
{
cout << endl;
}
}
data = reset;
But... You can also separate your logic out into functions and take advantage of pass by value
void fill(int * data,
int size)
{
for (int i = 0; i < size; i++)
{
*data = rand() % 100 + 1;
cout << setw(5) << right << *data++; // change made here
if ((i + 1) % 5 == 0)
{
cout << endl;
}
}
}
and the related part of main now looks something like
data = new int[size];
// Write a loop to fill the "data" array with random numbers from 1 - 100 (inclusive)
// This code must use POINTER NOTATION (no subscripting) to work with the array.
// Reminder: neither of these notations is acceptable here:
// data[n] or *(data + n)
// Instead this code will use pointer incrementing/decrementing and dereferencing
cout << "This is just the test to see if the pointer is successfully creating the array" << endl;
fill(data, size);
// Reset "data" to point to the beginning of the array
"Just wait a minute!" you're thinking. "How in Crom's name is int * data pass by value? That's a <expletive deleted>ing pointer!" The data pointed at is passed by reference, but the pointer itself is passed by value. data in fill is a copy of data in main. All of the data++ing in fill happens to a copy, so data in main is still pointing right where you left it.
No reset required and you've simplified main's responsibilities by spinning off part of them to their own simple and independently testable function. Keeping everything as simple, small, and stupid as possible is worth it's weight in bitcoin in my view.
#include <iostream>
using namespace std;
int* flipArray(int input[], int n)
{
int output[n];
int pos = 0;
for (int i = n-1; i >= 0; i--)
{
output[pos++] = input[i];
}
int* p = output;
for (int k = 0; k < n; k++)
cout << *p-k << endl << endl;
return p;
}
int main()
{
const int SIZE = 5;
int firstArray[SIZE];
for (int n = 0; n < SIZE; n++)
{
firstArray[n] = n+1;
}
int* a;
a = flipArray(firstArray, SIZE);
for (int j = 0; j < SIZE; j++)
cout << *a-j << endl;
cout << endl;
cout << *a << '\t' << *a+1 << '\t' << *a+2;
return 0;
}
I am attempting to flip firstArray using a function that returns a pointer, but I am struggling to understand how accessing an index using a pointer works.
Here is why I am confused:
Within the function flipArray, the following for-loop:
for (int k = 0; k < n; k++)
cout << *p-k << ' ';
prints "5 4 3 2 1" to the console. It was my understanding that I should be accessing an element of a vector with *(p+k), not *(p-k). If I print *(p+k), "5 6 7 8 9" is printed to the console. If I print the array without pointers and using k as the index location, "5 4 3 2 1" is printed to the console.
Within my main function, however, the values of *a which is assigned pointer p from the flipArray function, I do not get the same results:
for (int j = 0; j < SIZE; j++)
cout << *a-j << endl;
prints 5
0
-1
-2
-3 to the console, and
for (int j = 0; j < SIZE; j++)
cout << *a+j << endl;
prints 5
2
3
4
5 to the console.
Further, I thought that the pointer location of *p and the pointer of location of *a should be the same! But when I print the address &p in the function, I get the location of 0x28fde0, and when I print the address of &a in the main, I get the location 0x28fedc. Of course, these were done during the same run.
Could someone tell me where I have gone astray? Thanks!
Thanks to everyone for the informative answers.
I have updated my solution, and it is now returning what I would expect it to. I have a new question about memory leaks and when pointers need to be deleted.
int* flipArray(int input[], int n)
{
int* output = new int[n];
int pos = 0;
for (int i = n-1; i >= 0; i--)
output[pos++] = input[i];
return output;
}
int main()
{
const int SIZE = 5;
int firstArray[SIZE];
for (int n = 0; n < SIZE; n++)
{
firstArray[n] = n+1;
}
int* a;
a = flipArray(firstArray, SIZE);
for (int j = 0; j < SIZE; j++)
cout << a[j] << " "; // can also be written as *(a+j), which is more prone to bugs
delete [] a;
return 0;
}
Will the pointer output be deleted when the function flipArray returns? If not, how should I delete output while also returning it? Is deleting the pointer a in my main function the same thing as deleting output, because they point to the same location?
It has been pointed out that your main problem is coming from the operator precedence. The * operator in *p - k is evaluated before the -. This means that k will be subtracted from the value of the int pointed at by p.
This is a huge pain, which is why the braces pointer[k] are commonly used. There are situations where using pointer arithmetic *(pointer + k) makes more sense, but it can be a source of bugs.
One point to note here: it is always better to use parenthesis even if you are not sure whether or not you need them.
You do have a second problem:
Here you are declaring output on the stack as a local variable, then you are returning output. When you return back to the previous stack frame, this pointer will be pointing to a decallocated buffer:
int* flipArray(int input[], int n)
{
int output[n]; // allocated on the stack
int pos = 0;
for (int i = n-1; i >= 0; i--)
{
output[pos++] = input[i];
}
int* p = output;
for (int k = 0; k < n; k++)
cout << *p-k << endl << endl;
return p; // this stack frame ends.
}
This means the contents of the buffer can be overwritten if the space the buffer is using is reallocated. Use new to allocate on the heap:
int* output = new int[n];
make sure to call delete on the pointer when you are done using it.
This bug can even present security vulnerabilities in your applications, so make sure you know when to allocate on the heap in C++.
Update:
Question: When this function returns, the array still exists in memory, and it's location is stored in the pointer a. Does returning the value output delete it? If not, will deleting the pointer a when I am done with it in the main function serve the same purpose?
When you delete the pointer, the memory pointed to that pointer is deallocated and the pointer is left dangling. A reference to a deleted pointer is pointing at memory that is technically free, which is bad. If the allocator library decides that it wants to reuse that space, your buffer, which is now in free space, will be reallocated. This means your buffer will lose all data integrity and the data inside of it cannot be trusted.
A common practice is to assign pointers to NULL when you are done using them. This way your program will crash and you will know where your bug is:
int* p = new int[10];
...
delete p;
p = NULL;
...
p[0] = 0; // this will now crash because you are accessing NULL.
for (int k = 0; k < n; k++)
cout << *p-k ;
It was my understanding that I should be accessing an element of a vector with *(p+k), not *(p-k).
Your understanding is right.You are not accessing the array here.p points to the first element 5 and every time k is substracted from it, which gives you 5-0 5-1 5-2 and so on which is equivalent to the filpped array.So if you want to access the array using the pointer
for (int k = 0; k < n; k++)
cout << *(p+k) ;// Note the paranthesis
for (int k = 0; k < n; k++)
cout << *p-k << endl << endl;
What this code is doing is completely different from what you think it does.
*p - k will be processed like
*p = 5 - 0 = 5
*p = 5 - 1 = 4
and so on not *(p+k) or *(p-k)
For your understanding :
int a[5] = { 1,2,6,4,5};
In order to access 3rd element in the array you do
a[2] = *(a+2)
and not
*a + 2
*(a + 2) = 6 and *a + 2 = 1 + 2 = 3
Take care of not returning the pointer to the local variable which will lead to undefined behavior
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.
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]