Unable to understand the pointer mechanism - c++

Why is the program below crashing? I tried debugging the code but couldn't understand; I am suspecting that either the program is wrong or the memory to the passed pointer to display function should have been initialized.
#include <iostream>
using namespace std;
int display( int** intarray )
{
int size = 0;
while( size < 10 )
{
*intarray[size] = size;
size++;
}
return size;
}
int main() {
int* intptrarray;
int arraysize = 0;
arraysize = display( &intptrarray );
for ( int indx = 0; indx < arraysize; indx++ )
{
std::cout << intptrarray[indx] << std::endl;
}
return 0;
}

When a pointer is declared, it doesn't point to any specific memory address. To have it point somewhere, you need to allocate memory to it as follows:
#include <iostream>
using namespace std;
int display( int** intarray, int arraysize )
{
int size = 0;
while( size < arraysize )
{
(*intarray)[size] = size;
size++;
}
return size;
}
int main() {
int arraysize = 10;
int* intptrarray = new int[arraysize];
arraysize = display( &intptrarray, arraysize );
for ( int indx = 0; indx < arraysize; indx++ )
{
std::cout << intptrarray[indx] << std::endl;
}
delete[] intptrarray;
return 0;
}
Whenever you allocate memory, you need to remember to deallocate it yourself (delete for a single variable, delete[] for an array).

*intarray[size] should be (*intarray)[size].
However you have not yet allocated any memory either, so in both cases you are causing undefined behaviour by writing through an uninitialized pointer.
A correct way to write this program is:
void display( std::vector<int> &vec )
{
vec.resize(10);
for ( int i = 0; i < 10; ++i )
vec[i] = i;
}
int main()
{
std::vector<int> vec;
display(vec);
for ( int indx = 0; indx < vec.size(); indx++ )
{
std::cout << vec[indx] << std::endl;
}
}
This can be improved by using std::iota and range-based for-loops if you have a modern compiler.

Related

pass address of arr[0][2] , that must be received in a double pointer

need a better approach to pass address arr[0][2], given that is has to be received in a double pointer.
want to pass arr[0][2] without storing in any other variable.
#include <iostream>
using namespace std;
int help(int **arr)
{
cout<<**arr;
}
int main()
{
{
int n=3,m=3,k=0;
int **arr = new int*[n];
for(int i = 0; i < n; i++) {
arr[i] = new int[m];
}
for(int i = 0; i < n; i++) {
for(int j = 0; j < m; j++) {
arr[i][j]=k;
k++;
}
}
int *g=*arr+2;
int **h=&g;
help(h);
}
}
There is no better way. Unfortunately C++ syntax x[y] can be used to mean two very different operations: if x is an array then is indexing, if x is a pointer they it's indirection and indexing.
If a caller expects a pointer to a pointer and you've a bidimensional matrix there's nothing you can do except actually creating the pointer that is not present in the matrix and pass its address.
The fact that with an array of pointers, with a pointer to a pointer and with a 2d array the syntax to reach an element is x[y][z] is irrelevant... they are three very different operations.
Why not just write
int *p = &arr[0][2];
help( &p );
If you want to get an access to the whole array using a pointer of the type int ** then you can use the following approach.
#include <iostream>
void help(int **arr, size_t n )
{
for ( size_t i = 0; i < n; i++ )
{
std::cout << ( *arr )[i] << ' ';
}
std::cout << '\n';
}
int main()
{
int arr[2][3]={{1,2,3},{4,5,6}};
int *p = reinterpret_cast<int *>( arr );
help( &p, 6 );
return 0;
}
The program output is
1 2 3 4 5 6

What's wrong on passing this double pointer and get the value?

I'm new/noob programmer of C++, and I've this problem. I want to pass a pointer of double to a function (which will process some data on it) and read (after the process) a fixed value of that "array". I've do this:
void ReadDoubles(double* samples, int size)
{
for (int i=0; i < size; ++i)
{
*samples = i*10.1;
samples++;
}
}
int main()
{
int size = 10;
double *values=0;
ReadDoubles(values, size);
cout << *(values+3);
}
BUt of course it seems I can't init the pointer that way. I think I need to init the pointer allocating 10 values? Tried:
double *values[size];
but that's not the solution. How would you do this simple task?
You need to allocate the array at first. Here you are
#include <iostream>
void ReadDoubles( double* samples, size_t size )
{
for ( size_t i = 0; i < size; ++i )
{
*samples = i*10.1;
samples++;
}
}
int main()
{
size_t size = 10;
double *values = new double[size];
// ^^^^^^^^^^^^^^^^
ReadDoubles( values, size );
std::cout << *(values+3) << std::endl;
delete []values;
}
The program output is
30.3
If you don't want to use the operator new then there are two general approaches. Either you can declare an array as for example
int main()
{
const size_t size = 10;
//^^^^
double values[size];
// ^^^^^^^^^^^^
ReadDoubles( values, size );
std::cout << *(values+3) << std::endl;
}
or you can use standard class std::vector<double>.In this case the function should be rewritten appropriately.
For example
#include <iostream>
#include <vector>
void ReadDoubles( std::vector<double> &samples, size_t size )
{
samples.resize( size );
for ( size_t i = 0; i < size; ++i )
{
samples[i] = i*10.1;
}
}
int main()
{
size_t size = 10;
std::vector<double> values;
ReadDoubles( values, size );
std::cout << values[3] << std::endl;
}
If you are not allowed to change the RealDoubles function and you must have a function return the size then the following should work:
#include <string>
#include <iostream>
#include <math.h>
#include <cmath>
using namespace std;
void ReadDoubles(double* samples,int size)
{
for (int i=0; i < size; ++i) {
*samples = i*10.1;
samples++;
}
}
int get_size()
{
return 10;
}
int main()
{
int size = get_size(); // get size from function
//double *values=0;
double *values = new double[size] {0}; // Use new to allocate array. Optional: use {0} to init first element to 0, others default initialized to 0
ReadDoubles(values,size);
cout << *(values+3);
delete[] values;
}
If you prefer to avoid new and delete then you can let a std::vector manage the container for you:
#include <string>
#include <iostream>
#include <math.h>
#include <cmath>
#include <vector>
using namespace std;
void ReadDoubles(double* samples,int size)
{
for (int i=0; i < size; ++i) {
*samples = i*10.1;
samples++;
}
}
int get_size()
{
return 10;
}
int main()
{
int size = get_size(); // get size from function
//double *values=0;
std::vector<double> value_container(size,0); // vector will do the new and delete for us
double *values = value_container.data();
ReadDoubles(values,size);
cout << *(values+3);
} // vector destructor will do delete when it goes out of scope

Copying one array to another using pointers

I have to use pointers to copy values of one array to another. The problem is I'm not allowed to use'[ ]' operators, which makes this more difficult for me. Here is my attempt:
#include <iostream>
using namespace std;
void cpyia(int old_array[],int new_array[],int length){
int *p1 = old_array;
int *p2 = new_array;
int *x = p2;
for(int i=0 ; i<length ; i++){
p2 = x;
p2 = p2 + i;
p2 = p1 + i;
}
for(int i=0; i<5; ++i){
cout << p2[i] << endl;
}
}
int main() {
int a[5]={1,2,3,4,5};
int b[5];
cpyia(a, b, 5);
}
An easier way to do it would be to put p2[i] = p1[i] in the loop, but I cant do that. Any help is appreciated.
The standard way of implementing your function is as follow:
for(int i = 0; i < length; ++i)
*new_array++ = *old_array++;
To be a bit more explicit, it's the same as:
void cpyia(int old_array[],int new_array[],int length){
int *p1 = old_array;
int *p2 = new_array;
for(int i=0 ; i<length ; i++){
*(p2+i) = *(p1+i);
// another way: *(p2++) = *(p1++);
}
}
In real code, you would use std::copy before even thinking about rewriting such a simple thing yourself.
Here is a complete example:
#include <iostream>
#include <algorithm>
void cpyia(int old_array[],int new_array[],int length){
std::copy(old_array, old_array + length, new_array);
}
int main() {
int a[5]={1,2,3,4,5};
int b[5];
cpyia(a, b, 5);
// test results:
for (int index = 0; index < 5; ++index)
{
std::cout << a[index] << " <-> " << b[index] << "\n";
}
}
However, your question says that you are "not allowed to use" something, which sounds a lot like a homework assignment. In that case, you could look at possible implementations of std::copy to get an idea of how to do it. Here is one way:
void cpyia(int old_array[],int new_array[],int length){
int* first = old_array;
int* last = old_array + length;
int* d_first = new_array;
while (first != last) {
*d_first++ = *first++;
}
}
#include<iostream>
using namespace std;
int main() {
const int size = 5;
int arr1[size] = { 4,21,43,9,77 };
int arr2[size];
int *ptr_a = arr1;
int *ptr_b = arr2;
for (int i = 0; i < size; i++)
{
*(ptr_b + i) = *(ptr_a + i);
cout << *(ptr_b + i) << " ";
}
}

C++ Class with Dynamic Memory Allocation - Why am I getting this error?

I'm making a class called DblArray, and doing basic functions for it. I seem to be getting a problem when compiling, though, as it says "incorrect checksum for freed object - object was probably modified after being freed." I'll post all of my code below, but I think the problem is happening in this function:
void DblArray::insertVal(double n)
{
if ( size == capacity )
{
capacity *= 2;
double temp[size];
for ( int i = 0; i < size; i++ )
temp[i] = data[i];
delete [] data;
data = 0;
data = new double[capacity];
for ( int i = 0; i < size; i++ )
data[i] = temp[i];
}
size++;
data[size] = n;
}
The header file is this:
#include <iostream>
#ifndef DBLARRAY_H
#define DBLARRAY_H
class DblArray
{
private:
long capacity;
long size;
double * data;
public:
DblArray();
~DblArray();
DblArray(const DblArray& d);
DblArray& operator = (const DblArray& d);
double operator [] (int i);
long getCapacity();
long getSize();
double getAverage();
void insertVal(double);
void removeVal();
};
#endif // DBLARRAY_H
The implementation file is this:
#include "DblArray.h"
DblArray::DblArray()
{
capacity = 1;
size = 0;
data = new double[capacity];
}
DblArray::~DblArray()
{
capacity = 0;
size = 0;
delete [] data;
data = NULL;
}
DblArray::DblArray(const DblArray& d)
{
capacity = d.capacity;
size = d.size;
data = new double[capacity];
for ( int i = 0; i < size; i++ )
{
data[i] = d.data[i];
}
}
DblArray& DblArray::operator = (const DblArray& d)
{
DblArray dNew;
dNew.capacity = d.capacity;
dNew.size = d.size;
dNew.data = new double[capacity];
for ( int i = 0; i < dNew.size; i++ )
{
dNew.data[i] = d.data[i];
}
return dNew;
}
double DblArray::operator [] (int i)
{
return data[i];
}
long DblArray::getCapacity()
{
return capacity;
}
long DblArray::getSize()
{
return size;
}
double DblArray::getAverage()
{
double average = 0;
for ( int i = 0; i < size; i++ )
{
average += data[i];
}
average = average / size;
return average;
}
void DblArray::insertVal(double n)
{
if ( size == capacity )
{
capacity *= 2;
double temp[size];
for ( int i = 0; i < size; i++ )
temp[i] = data[i];
delete [] data;
data = 0;
data = new double[capacity];
for ( int i = 0; i < size; i++ )
data[i] = temp[i];
}
size++;
data[size] = n;
}
void DblArray::removeVal()
{
data[size] = 0;
}
And the driver is this:
#include <iostream>
#include "DblArray.h"
using namespace std;
DblArray print( DblArray );
int main()
{
//Data abstractions
DblArray d1;
//Printing the contents of d1 before testing functions
print(d1);
for ( int i = 0; i < 5; i++ )
{
d1.insertVal(i);
}
//Printing contents of d1 after adding values
print(d1);
return 0;
}
//Function to print the contents of each object
DblArray print( DblArray d )
{
cout << "Capacity:\t" << d.getCapacity() << endl;
cout << "Size:\t" << d.getSize() << endl;
cout << "Data:\t" << endl;
for ( int i = 0; i < d.getSize(); i++ )
{
cout << d[i] << "\t";
}
cout << "\n";
}
You have:
if ( size == capacity )
then you allocate:
data = new double[capacity];
so data is of size size. In the end you have:
size++;
data[size] = n;
this is writing outside array bounds and is the cause of undefined behaviour which can result in error you are getting
In insertVal(),
size++;
data[size] = n;
should be changed into
data[size++] = n;
Otherwise, when size == capacity-1, the data[size] = n; writes out of array boundary. The same issue also happens in removeVal().
Also the semantic of your operator=() is strange. It doesn't modify this at all, and returning reference to local object is wrong. Usually it should look like:
DblArray& DblArray::operator=(const DblArray& rhs) {
if (this == &rhs) return *this;
delete [] data;
data = new double[rhs.capacity];
capacity = rhs.capacity;
size = rhs.size;
// copy rhs.data[0] .. rhs.data[size-1] into data[]
return *this;
}
or define DblArray::swap() and perform copy-and-swap idiom.
There are quite a few problems in your source here, two that instantly sprang to me are as follows:
The function with the signature DblArray print(DblArray) does not return a value. You should change the signature to match the actual behaviour and you should also consider passing DblArray as a reference: void print(const DblArray& d)
The other issues I found have been raised by other answers. Out of curiosity, which compiler and platform are you using? Consider pasting your code in to an online compiler every now and then, gcc and clang tend to be very good with warnings if you are running in a Windows build environment. In particular, I use Coliru. You can customise the compiler flags to show more, or less warnings, and so on. With your example, you should be able to just paste everything you have written here, removing any #include <DblArray.h> directives, and be good to go.

Getting out of scope error with dynamically allocated array

I am getting an out of scope error in my copy function, when I try to copy the contents of the first array into the DMA one. The try-catch block is required.
#include <iostream>
#include <cstdlib>
using namespace std;
void show( const int a[], unsigned elements );
int * copy( const int a[], unsigned els );
void die(const string & msg);
int main()
{
int arr[4] = {4, 2, 3, 6};
show(arr, 4);
int * newArr = copy(arr, 4);
}
void show( const int a[], unsigned elements )
{
for (int i = 0; i < elements; i++)
cout << a[i] << endl;
}
int * copy( const int a[], unsigned els )
{
try
{
int * newArr = new int[els];
}
catch(const bad_alloc &)
{
die("Alloc Failure");
}
for (int i = 0; i < els; i++)
newArr[i] = a[i];
return newArr;
}
void die(const string & msg)
{
cerr << "Fatal error: " << msg << endl;
exit(EXIT_FAILURE);
}
If you declare the variable inside the try block then it's only accessible there. You can work around this by moving the declaration outside of the block.
int *newArr;
try
{
newArr = new int[els];
}
catch(const bad_alloc &)
{
die("Alloc Failure");
}
for (int i = 0; i < els; i++)
newArr[i] = a[i];
Or by moving the rest of the code inside the try.
try
{
int *newArr = new int[els];
for (int i = 0; i < els; i++)
newArr[i] = a[i];
return newArr;
}
catch(const bad_alloc &)
{
die("Alloc Failure");
}
Define new array before the try, otherwise it is only defined inside the try block.
The whole point of exceptions is that you do not need to handle all conceivable errors right at the point where they happen, but rather in places of your choice where you are able to respond to them meaningfully. So be generous with the size of your try blocks:
int * copy(const int a[], unsigned els)
{
try
{
int * newArr = new int[els];
for (int i = 0; i < els; i++)
newArr[i] = a[i];
return newArr;
}
catch (const std::bad_alloc &)
{
die("Alloc Failure");
}
}
You can change your code to
int * copy( const int a[], unsigned els ) {
int * newArr = nullptr;
try {
newArr = new int[els];
}
catch(const bad_alloc &) {
die("Alloc Failure");
}
if(newArr) {
for (int i = 0; i < els; i++)
newArr[i] = a[i];
}
return newArr;
}
to overcome your problem. Just initialize newArr correctly.
I think the problem in your Copy-Function is, that the new Array is a local Variable. When you than return it to the caller, the pointer adresses aren't the right ones.
You might better use two arrays which you pass as Referneces into the copy-function, like this:
int& copy(int& newArray, const int& oldArray) { ... }
Here you get a discription about references in c++ if you don't know what they supposed to be: http://en.wikipedia.org/wiki/Reference_%28C%2B%2B%29