I want to have a function which initializes dynamic 2d arrays in cpp like below
void initArrays(int n,double **a,double **b,double **c) {
a = new double*[n];
for (int i = 0; i < n; i++)
a[i] = new double[n];
b = new double*[n];
for (int i = 0; i < n; i++)
b[i] = new double[n];
c = new double*[n];
for (int i = 0; i < n; i++)
c[i] = new double[n];
}
The function call completes but it does not initialize the pointers I give as function arguments.
For example if I call this function in the main
double **x,**y,**z;
initArrays(3,x,y,z);
I cannot access
x[0][0]
what am I doing wrong here?
The pointers stay uninitialized because you never assign them a value. The pointers in your init function are copies of the ones that you passed. You can pass the pointers by reference:
void initArrays(int n,double **&a,double **&b,double **&c)
That said, you'll probably be better off with std::vector.
Related
I am trying to build some .cpp code, in an XCode project. I have a very simple function that converts a matrix of data type cv::Mat (from opencv), to a simple two-dimensional c++ array.
The function looks something like this:
int* myClass::convertMatrix(cv::Mat cvmat){
int r = cvmat.rows;
int c = cvmat.cols;
int newmat[r][c];
for(int i=0; i<r; i++){
for(int j=0; j<c; j++){
newmat[i][j] = cvmat.at<int>(i, j);
}
}
return newmat;
}
I can't figure out what's wrong. I know "lvalue" refers to a specific memory location, but what does this have to do with me returning a matrix?
You're trying to return a pointer to a temporary variable inside that function.
After the function is being returned, that variable is automatically being cleaned up by the compiler.
Also, you are trying to create a stack-allocated array with parameters that are unknown at compile-time, if you had the size of the array at compile-time, you could have marked r and c as constexpr, if it didn't complain about that consider reading about VLA.
To fix those issues, just allocate the array on the heap:
int** make_2d_array(int r, int c)
{
int** arr = new int*[r];
for(int i = 0; i < r; i++)
arr[i] = new int[c];
return arr;
}
int** myClass::convertMatrix(cv::Mat cvmat){
int r = cvmat.rows;
int c = cvmat.cols;
int** newmat = make_2d_array(r, c);
for(int i=0; i<r; i++){
for(int j=0; j<c; j++){
newmat[i][j] = cvmat.at<int>(i, j);
}
}
return newmat;
}
Don't forget to delete the array when you stopped using it.
I also recommend considering using std::vector for that, so you don't have to worry about deleting the array ( way simpler ):
std::vector<std::vector<int>> newmat(r, std::vector<int>(c));
Hy guys, I actually Trying to create a 2D Array in c++ but not able to create that, When I execute the following statement
int arr=new int[10][10]
It gives me error and when I search on google it shows me 2D array in c++ is array of pointers which is declare like the below statements
int** a = new int*[rowCount];
for(int i = 0; i < rowCount; ++i)
a[i] = new int[colCount];
I got the logic which is a is a pointer to pointer to the matrix but now I am not able understand the logic like how can i point to the data on this matrix, Suppose to see the number store in index a[0][0] should i write
cout<<a[0][0]
or not, I am not able to get the logic how this pointer to pointer will work when with the pointers pointing to the matrix, and one more thing is that I am not able to pass it as an argument to a function. The code for passing it as a parameter is given below
void displayArray(int a[10][10])
{
for (int i=0; i<10; i++)
{
for(int j=0; j<10; j++)
{
cout<<*a[i][j]<<"\t";
}
cout<<endl;
}
}
int main()
{
int** a = new int*[10];
for(int i = 0; i < 10; ++i)
a[i] = new int[10];
displayArray(**a);
}
It giving me the following error
error: invalid conversion from ‘int’ to ‘int (*)[10]’ [-fpermissive]
Actually I am not able to get any sense of how to use the pointer to pointer in a matrix, it's too complex compared to other languages where we just need to use new operator and can access them with their dimensions, No need of this pointer to pointer concept. Please help me understanding the whole logic of this 2d dynamic array of c++.
you need to get the parameter in your function as pointer
void displayArray(int **a)
{
for (int i=0; i<10; i++)
{
for(int j=0; j<10; j++)
{
cout<< a[i][j] <<"\t";
}
cout<<endl;
}
}
int main()
{
int** a = new int*[10];
for(int i = 0; i < 10; ++i)
a[i] = new int[10];
displayArray(a);
}
it prints 10 rows and columns of value 0 because the 2D array is uninitialized
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.
I try to define a 2D array with C++ with pointers and I don't know how can I define it true? I have some loops in the function and they are start with 1 to n and I want to allocate memory and at the end of function I want to delete allocated memory?
for define it like the following code. please help me to develop it.
int **W;
W = new int* [n];
for (int i=1; i <= n; i++)
W[i] = new int[n];
///////////////////////
for (int k=1;k<=n;k++)
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
do some thing!
///////////////////////
for ( int i = 1; i <= n; i++ )
delete [] W[i];
delete W;
For an array of size n, indices start from 0 - (n-1). Thus array[n] is out of bounds.
int **W;
int n = 3;
W = new int*[n];
for (int i = 0; i < n; i++)
W[i] = new int[n];
for (int i = 0; i < n; i++)
delete[] W[i];
delete W;
You have the general idea correct. But there are some errors in the details. C/C++ use 0-based indices to access arrays.
for (int i=1; i <= n; i++)
W[i] = new int[n];
needs to be
for (int i=0; i < n; i++)
W[i] = new int[n];
Similar changes need to be made in the other for statements.
Also, you need to delete W using the array delete operator. Instead of
delete W;
use
delete [] W;
Having said that, you should use std::vector instead of plain old dynamic arrays. With std::vector, you don't have to worry about deallocation of memory. The destructor of std::vector will take care of deallocating memory.
A 2D array of size n x n where each element is initialized to 0 can be defined simply as:
std::vector<std::vector<int>> array(n, std::vector<int>(n, 0));
CASE1:
int nrows=5;
int ncols=10;
int **rowptr;
rowptr=new int*;
for(int rows=0;rows<nrows;rows++) {
for(int cols=0;cols<ncols;cols++) {
*rowptr=new int;
}
}
CASE2:
int nrows=5;
int ncols=10;
int **rowptr;
for(int rows=0;rows<nrows;rows++) {
rowptr=new int*;
for(int cols=0;cols<ncols;cols++) {
*rowptr=new int;
}
}
I am able to insert and print values using both ways. What is the difference in initializations?
What is the difference?
#1 just allocates memory enough to hold a integer pointer and not an array of integer pointers.
#2 Causes a memory leak by just overwritting the memory allocation of the previous iteration.
I am able to insert and print values using both the ways
Memory leaks and Undefined behaviors may not produce immediate observale erroneous results in your program but they sure are good cases of the Murphy's Law.
The correct way to do this is:
int nrows = 5;
int ncols = 10;
//Allocate enough memory for an array of integer pointers
int **rowptr = new int*[nrows];
//loop through the array and create the second dimension
for (int i = 0;i < nrows;i++)
rowptr[i] = new int[ncols];
You have a memory leak in both cases.
The proper way to initialize such a "2d" array is
int** arr = new int*[nrows];
for (int i = 0; i < nrows; i++)
arr[i] = new int[ncols];
Note however, that it isn't a 2d array as defined by C/C++. It may not, and probably will not, be consecutive in memory. Also, the assembly code for accessing members is different.
In your case, the accessing by indexing is equivalent to *(*(arr+i)+j)
And in the case of a 2d array it's *(arr + N_COLS*i + j) when N_COLS is a compile time constant.
If you want a true 2d array you should do something like this:
int (*arr)[N_COLS] = (int(*)[N_COLS])(new int[N_ROWS * N_COLS])
You'd better use 1d array to manage 2d array
int **x = new int*[nrows];
x[0] = new int[nrows*ncols];
for (int i = 1; i < nrows; i++)
x[i] = x[i-1] + ncols;
for (int i = 0; i < nrows; i++)
for (int j = 0; j < ncols; j++)
x[i][j] = 0;
delete [] x[0];
delete [] x;