An array passed to a function gives nan elements (C++) - c++

I have a function that takes in an array and defines a new array made up of a subset of the original array.
#include<iostream>
#include<cmath>
using namespace std;
double * subarray(double *array){
double *sub= new double[100];
for (int i=0; i<10; i++){
sub[i]=array[i];
}
return sub;
}
int main(){
double *x=new double[100];
double *y=new double[10];
for(int j=0; j<100; j++){
x[j]=sin(j*3.14/2.0);
}
y=subarray(x);
for(int k=0; k<10; k++){
cout<<y[k]<<endl;
}
return 0;
}
When I run this code some of the elements of the sub array come out as nan.

calling subarray is creating a new double[100] then passing that back out. But it's a completely separate array to y = new double[10]. Whenever you call "new" it's making a new thing, separate to all other "new" things. y gets the address of the "new double[100]" but it loses track of the address of the "new double[10]" you made in main, which is a memory leak. If you're going to return a pointer to an new'ly allocated item, start the pointer that's going to store it as a nullptr, and call "delete" or "delete []" when you're done, depending on whether it was a "new[]" thing or just "new".
#include<iostream>
#include<cmath>
using namespace std;
double * subarray(double *array) {
double *sub = new double[10]; // don't allocated more than you want to use
for (int i = 0; i < 10; i++) {
sub[i] = array[i];
}
return sub;
}
int main() {
double *x = new double[100];
double *y = nullptr; // don't set this if you're going to overwrite it
for (int j = 0; j < 100; j++) {
x[j] = sin(j*3.14 / 2.0);
}
y = subarray(x);
for (int k = 0; k < 10; k++) {
cout << y[k] << endl;
}
delete [] x; // if you make new things, delete them afterwards
delete [] y;
std::cin.get();
return 0;
}
I don't get any NaNs when I run this, but you are allocating a lot of memory that never gets set, inside the function. You're allocating 100 spaces but only writing to 10. This isn't necessarily an error, but it's not efficient.

Related

I am having a bad access issue

I am trying to create a merge function for two array structures in c++ but am coming up with a bad access error that I don't know how to solve. The error comes up when I am trying to swap the element in the smaller array into the larger, merged array. The code doesn't even go through a single iteration. All three of i, j, and k remain at 0. Any help would be greatly appreciated! Here is the code:
struct Array
{
int *A;
int size;
int length;
};
void display(Array arr){
for (int i = 0; i < arr.length; i++)
std::cout << arr.A[i] << std::endl;
}
Array merge(Array arr1, Array arr2){
Array arr3;
arr3.length = arr1.length + arr2.length;
arr3.size = arr1.length + arr2.length;
int i = 0, j =0, k =0;
while(i <arr1.length && j < arr2.length){
if (arr1.A[i] < arr2.A[j])
{
arr3.A[k] = arr1.A[i]; //(The error is displayed here: Thread 1: EXC_BAD_ACCESS (code=1, address=0x28))
k++;
i++;
}
else if (arr2.A[j] < arr1.A[i])
{
arr3.A[k] = arr2.A[j];
k++;
j++;
}
}
for (; i< arr1.length; i++)
{
arr3.A[k]=arr1.A[i];
k++;
}
for (; i< arr2.length; j++)
{
arr3.A[k]=arr2.A[j];
k++;
}
return arr3;
}
int main() {
Array arr1;
arr1.size = 10;
arr1.length = 5;
arr1.A = new int[arr1.size];
arr1.A[0]= 2;
arr1.A[1]= 6;
arr1.A[2]= 10;
arr1.A[3]= 15;
arr1.A[4]= 25;
Array arr2;
arr2.size = 10;
arr2.length = 5;
arr2.A = new int[arr2.size];
arr2.A[0]= 3;
arr2.A[1]= 4;
arr2.A[2]= 7;
arr2.A[3]= 18;
arr2.A[4]= 20;
Array arr3 = merge(arr1, arr2);
display(arr3);
return 0;
}
Your Array arr3 does not allocate any memory for its int *A field. It's natural that it would not work.
Anyway, your implementation of Array is very poor. Don't reimplement arrays unless you have a good reason; use std::vector instead.
If you really need to implement an Array on your own, then learn about encapsulation, make a class with a constructor, and allocate/delete your data (*A) field properly. Remember, using pointers and heap memory without understanding them is a recipe for disaster.
Easy: arr3.A is not initialized. It's a pointer. What does it point to?
Suggestion: learn about dynamic memory allocation.

Using uninitilized variable in a method

I'm writing a simple program within which a dynamic array is to be created. The function that is being used to create said array is in a second .cpp file, attached as a user-made library. Unfortunatelly Visual Studio pops an error saying that the program can't use uninitialized variable. I feel like it's a really easy problem to solve, but I don't know how to get through it. Here is the code:
int main()
{
int i = 5, j = 6;
string** Array;
createDefStruct(Array, i, j);
/*for (int k = 0; k < i; k++)
{
for (int m = 0; m < j; m++)
{
Array[i][j] = "YIKES";
cout << Array[i][j] << '\t';
}
cout << endl;
}*/
deleteDefStruct(Array, i);
return 0;
}
The createDefStruct function:
void createDefStruct(string** Arr, int varAttribCount, int varCount)
{
Arr = new string * [varAttribCount+1];
for (int i = 0; i < varAttribCount+1; i++)
Arr[i] = new string[varCount];
}
How do I go about initilizing a variable?
Thank you in advance!
So the problem is that instead of returning your array from the function you passed the array into the function as parameter. This mean that the variable is uninitialised in main (even though it is initiialised in createDefStruct). Rewrite like this
string** createDefStruct(int varAttribCount, int varCount)
{
string** Arr = new string * [varAttribCount+1];
for (int i = 0; i < varAttribCount+1; i++)
Arr[i] = new string[varCount];
return Arr;
}
int main()
{
int i = 5, j = 6;
string** Array = createDefStruct(i, j);
...
In general when you want a function to return a value you use return from inside the function to return that value. When you want to pass a value into a function you use a parameter. In your createDefStruct function varAttribCount and varCount are the parameters but the array should be a return value.

How can I allocate memory for triple pointer using a function?

I would like to allocate memory to store/manipulate data using a triple pointer. Given that I have to allocate the data at multiple points in my code, I implemented a function to do it. In the code below I give the implementation of this function and a simple main method that illustrates how I use this function in my code.
The code compile without error but when I run the program it crushes. I would appreciate your help to fix this problem.
EDIT: it crushes in the function AllocateMemory at the line
*data[i][j] = new double[x];
for i = 0 and j =1
Thank you.
int main()
{
int x = 2;
int y = 2;
int z = 2;
double*** data;//
AllocateMemory(&data, x, y, z);
//play with data
FreeMemory(data, x, y, z);
return 0;
}
void AllocateMemory(double**** data, int x, int y, int z)
{
*data = new double**[z];
for(int i = 0; i < z; i++)
{
*data[i] = new double*[y];
for(int j = 0; j < y; j++)
{
*data[i][j] = new double[x];
}
}
}
void FreeMemory(double*** data, int x, int y, int z)
{
for(int i = 0; i < z; i++)
{
for(int j = 0; j < y; j++)
{
delete [] data[i][j];
data[i][j] = NULL;
}
delete [] data[i];
data[i] = NULL;
}
delete [] data;
data = NULL;
}
Remember that array subscription has a higher precedence than dereference operator. Here:
*data[i] = new double*[y];
You're subscripting data and then dereferencing that pointer. data argument of AllocateMemory is not a pointer to an array, but instead to a single variable which is data in main. Therefore data[1] was never initialized and you get undefined behaviour. Given the context, you probably intended it the other way round:
(*data)[i] = new double*[y];
You have the same bug on the line *data[i][j] = new double[x];.
You could have avoided this either by using a reference parameter or - as I would recommend - by returning the pointer to the newly allocated array of pointers instead of passing it as an argument.

Deleting Arrays With Pointers--Multidimensional and Multipointer---in C++

So I know multiple dimensions/arrays can get confusing, but how do I delete these types of arrays properly? I know the syntax, but adding multiple dimensions/pointers gets tricky. Here's some snippet code:
//FIRST PROBLEM
//function to add an item to a pointer array
//due to problems in adding something directly, I created a temp
//temp is not necessary if there's a way without it
int y = 6;
int x = 5;
int *myList = new int[x];
void List::add(int newInt)
{
void List::add(int newInt){
int *temp = new int[x+1];
temp = myList;
temp[x+1] = newInt;
delete [] myList;
int *myList = temp;
}
//SECOND PROBLEM----tricky multidimensional
// not getting any errors, but not sure if done properly
int x;
int y;
int** myMatrix;
cout << "How many rows?" << endl;
cin >> x;
myMatrix = new int*[x];
cout << "How many columns?" << endl;
cin >> y;
for (int i=0; i<x; i++)
myMatrix[i] = new int[y];
for(int i=0; i<10; ++i){
for(int j=0; j<10; ++j){
myMatrix[i][j] = rand();
}
for(int i = 0 ; i < x ; ++i)
{
for(int j = 0 ; j < col ; ++j){
// delete[] myMatrix[i][j]; (tried this method, did not work)
}
delete[] myMatrix[i];
}
delete[] myMatrix;
//looked around for examples, but were all different enough to not help
//
// delete[] myMatrix[i][j]; (tried this method, did not work)
The code you have here
myMatrix[i][j] = rand();
doesn't allocate any new heap memory for myMatrix[i][j] (which is of a non pointer type, but a simple int BTW), but just assigns the result of rand() as a value there.
Thus it's not necessary/wrong, you ever call delete for it.
You only call delete/delete[] as counterparts of new/new[] in the reverse order as they were allocated.
Further, to get redeemed from struggling with memory management, I'd seriously recommend using a c++ standard container like std::vector<std::vector<int>> myMatrix; instead of managing raw pointers.

Corrupted heap error when declaring a double* array

I'm currently working on finding the sum of squared distances of two matricies, the data is held in double* arrays. the first of them stays the same while the other is cycled through using a function that returns a 32x32 array between two indices.
However when i try and call "getTile(d,e)" after the first incrementation of "e" it throws a heap corruption exception:
double* Matrix::ssd(int i, int j, Matrix& rhs){
double sum = 0, val = 0; int g = 0, h=0;
double* bestMatch = new double[32*32]; double* sameTile = new double[32*32]; double* changeTile = new double[32*32];
for(int x = i-32; x <i; x++){
for(int y = j-32; y <j; y++){
sameTile[g*32+h] = data[x*N+y];
h++;
}g++; h = 0;
}
system("pause");
for(int d = 32; d<=512; d+=32){
for(int e = 32; e<=512; e+=32){
changeTile = rhs.getTile(d,e);
for(int out = 0; out < 32; out++){
for(int in = 0; in < 32; in++){
val = sameTile[out*32+in] - changeTile[out*32+in];
val = val*val;
sum = sum + val;
}
}
cout << sum << endl;
sum = 0; val = 0;
system("pause");
}
}
The getTile(int i, int j) function:
double* Matrix::getTile(int i, int j){
double* tile = new double[32*32]; int g = 0; int h = 0;
for(int x=i-32; x<i; x++){
for(int y=j-32; y<j; y++){
tile[g*32+h] = data[x*N+y];
h++;
}
cout << endl;
g++;
}
return tile;
}
I believe the error occurs with the allocation of memory in the changeTile double*?
Any help would be very much appreciated.
There are a bunch of issues in your code all related to improperly accessing array elements.
In the first loop the line:
sameTile[g*32+h] = data[x*N+y];
at the very least underflows the data array. Consider if i=0, j=0, and N=512 then you are trying to access data[-16416] in the first pass of the loop.
Second issue is the getTile() method where you forget to reset h to 0 at the end of the inner loop (like you do in the ssd() method). This results in the overflow of tile[]
I would also double-check the line:
changeTile = rhs.getTile(d, e);
and the method getTile() to ensure an array overflow doesn't occur on data[].
Overall I would suggest using proper std:: containers if at all possible. Using them correctly should completely eliminate this type of error. If you really do need to use raw pointers/arrays then you need to make sure all your indexing into them is as clear as possible in addition to bounds checking where needed.