Characters duplicate in a multidimensional array - c++

I have created an empty char multidimensional array, but when I try to change a specific value, it sometimes duplicates to another space in the array.
Example:
#include <iostream>
using namespace std;
char arr[2][2] = { 0 };
int main ()
{
arr[2][0] = 'A';
for(int i = 0; i < 3; ++i)
{
for(int j = 0; j < 3; ++j)
{
cout << "arr[" << i << "][" << j << "] = " << arr[i][j] << endl;
}
}
}
Output:
arr[0][0] =
arr[0][1] =
arr[0][2] =
arr[1][0] =
arr[1][1] =
arr[1][2] = A
arr[2][0] = A
arr[2][1] =
arr[2][2] =
The character A should only appear in [2][0] but it also appears in [1][2].
This happens only in these spaces:
[1][0], [2][0], [0][2], [2][2]
I was able to recreate this with a bigger array, but I can't say the specific values.
I have tried defining inside the main() function but it created another problem, random characters started appearing in random locations of the array.
I tried initializing the array with char arr[2][2] = { 0 }, but it didn't help.

When you declare char arr[2][2] = { 0 };, that's a 2x2 array. Which means it's indices go from 0 to 1. You're writing into index 2, which is outside of array bounds.

There is probably some memory bashing happening.
When you declare an array as char arr[2][2] = { 0 }; array of two arrays of size two of char. Which means 4 char elements.
You can access them as
arr[0][0];
arr[0][1];
arr[1][0];
arr[1][1];
For your code to work you need to buff up the size of the array to char arr[3][3] = { 0 };
To answer your question why are they duplicated.
The memory continues when you allocate char arr[2][2] it will allocate space for 4 elements and it might be the same as char arr[4].
When you try to access an element out of the bounds of your array the behavior is undefined at it resulted in accessing the memory of the second array.

That's because you're going past your array. An array of char arr[2] only goes from 0 to 1 (that's 2 values). Similarly, for your arr[2][2] you can also only use 0 and 1 as array index.
Try this instead:
char arr[3][3] = { 0 };
Now the array index can go from 0 to 2.

Related

How can I find the number of elements in an already declared array of size n, if it's partially filled?

Suppose I created an array of size 5. Filled two number 1 and 2 at index 0 and 1 respectively. Now I want to return number of elements currently present in the array, i.e. 2 and not 5 given by size below. How can I do that?
int arr[5];
arr[0] = 1;
arr[1] = 2;
//size returns 5 but I want it to return 2, since it has only 2 elements.
int size = sizeof(arr)/sizeof(arr[0]);
cout << size;
If you use a classic array, it is not possible to do what you say, you will get 5 outputs each time. But if you use std::vector, the size of the vector will change automatically every time you add a new element to the vector. Then, you can easily count the number of elements in the vector by using the size() function. you can print to the screen.
#include<iostream>
#include<vector>
int main() {
std::vector<int> vec;
for (size_t i = 1; i <= 2; ++i) { vec.push_back(i); }
std::cout << "number of elements= " << vec.size();
return 0;
}

c++ array of pointers and memory address allocation

Can someone explain how an array of pointers implementation of c++ dynamically?
Is the below code correct?
If so,
int *ptr[5];
for (int i = 0; i < 5; i++)
{
int size = 2;
ptr[i] = new int [size] ;
//*(ptr + i) = new int[size]; this is the same as above line
cout << &ptr[i] << endl; ----------> line 1
cout << ptr[i] << endl; -----------> line 2
}
What is actually printing in line 1 and 2 ?
this is the addresses i get for line 1
0x7fff88f805d0
0x7fff88f805d8
0x7fff88f805e0
0x7fff88f805e8
0x7fff88f805f0
this is the addresses I get for line 2
0x55f946348ef0
0x55f946349330
0x55f946349360
0x55f946349390
0x55f9463493c0
Can somebody explain this whole mess of pointer arrays.
The picture provides a graphical explanation to the problem if anyone gets
confused with the array of pointers concept with dynamically allocating the array of pointers to new int or any other type array
int *ptr[2]; // statically declared pointer array stack
int p [2];
for (int i = 0; i < 2; i++)
{
int size = 2;
ptr[i] = new int[size];
cout << i << " array of int " << endl;
//*(ptr + i) = new int[size];
for (int j = 0; j < size; j++)
{
cout << "value : " ;
cout << *(ptr[i] + j) ; // <------- this should give 0's as value
//cout << (ptr[i])[j] ; <------ same thing
cout << " address :";
cout << ptr[i] + j << endl; //<----- these are in order as well since it's an array of type int
}
}
0 array of int
value : 0 address :0x564c9ede32c0
value : 0 address :0x564c9ede32c4
value : 0 address :0x564c9ede32c8
1 array of int
value : 0 address :0x564c9ede32e0
value : 0 address :0x564c9ede32e4
value : 0 address :0x564c9ede32e8
I am assuming you want to perform operation on dynamic array like adding element and printing;
Remember:In int *ptr=new int[5]; sizeof(ptr) is 8 bytes on stack memory and array will be stored in heap memory.
We will fetch the element via pointer ptr and every element will be fetched as per type of array (say int ) then ptr will go to 0th index element and read the data of it as int type (only 4 bytes as int is of 4 byte generally) and move to next index till end.
Look into code below:
#include <iostream>
using namespace std;
int main() {
int *ptr=new int[5]; //let size = 5
for(int i=0; i<5;i++){
cin>>ptr[i];
}
for(int i=0; i<5;i++){
cout<<&ptr[i]<<":"; //this will print every element's address per iteration
cout<<ptr[i]<<endl; //this will print every element as per input you gave
}
delete []ptr; //remember it's not delete ptr ask if required
return 0;
}
Now See the the output and dry run yourself you can understand
Output
0x556999c63e70:1
0x556999c63e74:2
0x556999c63e78:3
0x556999c63e7c:4
0x556999c63e80:5
Benefit of dynamic array is you can create dynamic sized array by taking size input as per user choice pass that variable is size of dynamic array
i.e you can change above size=5 to 'N' a variable one .
I think this might help you else you can ask for any further clarification.

Explanation of undefined behaviour, and whether it's truly undefined

I have dynamically allocated memory for an array of 5 elements, then tried to print its elements to std::cout, which should have left me with a fairly straightforward result. I got something else instead, and it left me with some questions.
My code:
#include <iostream>
int main()
{
int *array = new int[5];
int array_size = sizeof(array);
for (int index = 0; index < array_size; index++) {
std::cout << array[index] << "\n";
}
std::cout << "\nThe array is " << array_size << " elements long.";
return 0;
}
This is what this resulted in:
0
0
0
0
0
0
132049
0
Now, I understand this isn't how things are done, but such a result has left me with several questions.
Why is the size of the array 8, and not 5? Originally, I thought that it's becase the memory according to powers of 2, but I have a feeling I'm wrong.
What's with 132049?
Your code has two problems, each of them leading to undefined behavior.
First, sizeof(array) is the size of the pointer in bytes, not the array. On your machine, a pointer happens to take 8 bytes. This causes out-of-range access, which is undefined behavior.
Second, new int[5] gives you an uninitialized array. Accessing the value of an uninitialized object is undefined behavior.
To fix these problems, first note that the size of an array returned by new is lost. sizeof cannot help you. You can only provide this information yourself. Then you have to initialize the elements.
#include <iostream>
int main()
{
int *array = new int[5]{}; // note: initialization
int array_size = 5;
for (int index = 0; index < array_size; index++) {
std::cout << array[index] << "\n";
}
std::cout << "\nThe array is " << array_size << " elements long.";
return 0;
}
This is code is guaranteed to print
0
0
0
0
0
The array is 5 elements long.
(As long as there is enough memory and output succeeds)

Writing a loop to change the value in a int array with different names

My title is a bit confusing, but I'm trying to write a loop that will change the value in 81 arrays with different names. I want to either initiated the array with a value or an array of values. This is part of my sudoku solver code since I don't think I'm explaining it well.
int cell1[], cell2[9], cell3[9],cell4[9]......cell81[9]; // <-- this will make 81 cells with an array that can hold a possible of 9 candidates
cout << "User input: << endl; // lets use ...1.5...14....67..8...24...63.7..1.9.......3.1..9.52...72...8..26....35...4.9...
// as an example
Let's assume I store that input into a Char Array and I'm going to use a loop to decide whether to initiate the given value or '.' as an empty value.
For empty values, I'm looking to initialize the array with 1-9 values. I can do this easily with this code.
If( ( (int)charArray[ 0 ] - 48) > 0 ) { // type cast to int. Neg = initialize array with 1-9
// pos = initialize with original value
cell1[ 0 ] = (int)charArray[ 0 ] - 48;
} else {
cell1[ 9 ] = { 1,2,3,4,5,6,7,8,9};
}
I want to avoid writing this code 81 times for 81 cells ( Considered as writing junk code ). I can't figure out how to write the loop. I'm open to suggestions on how I can code this different using classes, functions, and etc. Thanks in advance.
Create the cell array as a 2-dimensional array, with 81 rows and 9 columns.
int cell[81][9];
Now you can loop through them using the syntax cell[r][c]. For instance,
for( i = 0; i < 81; ++i ) {
cell[i][0] = 1;
// ...
cell[i][8] = 9;
}
If you'd prefer to avoid 2-D arrays, you can declare the array as a 1-dimensional array, and just index into it appropriately.
int cell[81 * 9];
for( i = 0; i < 81; ++i ) {
cell[i + 0*81] = 1;
// ...
cell[i + 8*81] = 9;
}
int a1[9],a2[9],a3[9],a4[9],...
void init_array(int *ptr, const char *chr, int len, int start){
for(int i = start; i < len; i++){
if(chr[i] == '.')continue;
ptr[i] = chr[i]-'0';//converts character to integer.
}
}
int main(int argc, char **argv)
{
std::string str;
cin >> str;
init_array(a1,str.c_str(),9,0); init_array(a2,str.c_str(),9,9/*increment by 9*/);...
//..
return 0;
}
Write a function called init_array() that accepts an integer pointer and initializes the array for you. You can avoid duplicating the code this way.

Cannot Convert from int[][] to int*

I have a 3x3 array that I'm trying to create a pointer to and I keep getting this array, what gives?
How do I have to define the pointer? I've tried every combination of [] and *.
Is it possible to do this?
int tempSec[3][3];
int* pTemp = tempSec;
You can do int *pTemp = &tempSec[0][0];
If you want to treat a 3x3 array as an int*, you should probably declare it as an int[9], and use tempSec[3*x+y] instead of tempSec[x][y].
Alternatively, perhaps what you wanted was int (*pTemp)[3] = tempSec? That would then be a pointer to the first element of tempSec, that first element itself being an array.
You can in fact take a pointer to a 2D array:
int (*pTemp)[3][3] = &tempSex;
You'd then use it like this:
(*pTemp)[1][2] = 12;
That's almost certainly not what you want, but in your comment you did ask for it...
Its easyier to use a typedef
typedef int ThreeArray[3];
typedef int ThreeByThree[3][3];
int main(int argc, char* argv[])
{
int data[3][3];
ThreeArray* dPoint = data;
dPoint[0][2] = 5;
dPoint[2][1] = 6;
// Doing it without the typedef makes the syntax very hard to read.
//
int(*xxPointer)[3] = data;
xxPointer[0][1] = 7;
// Building a pointer to a three by Three array directly.
//
ThreeByThree* p1 = &data;
(*p1)[1][2] = 10;
// Building a pointer to a three by Three array directly (without typedef)
//
int(*p2)[3][3] = &data;
(*p2)[1][2] = 11;
// Building a reference to a 3 by 3 array.
//
ThreeByThree& ref1 = data;
ref1[0][0] = 8;
// Building a reference to a 3 by 3 array (Without the typedef)
//
int(&ref2)[3][3] = data;
ref2[1][1] = 9;
return 0;
}
Oh. That's easy!
int aai[3][3];
int* pi = reinterpret_cast<int*>(aai);
You can actually use this awesome technique to cast it into other wonderful types. For example:
int aai[3][3];
int (__stdcall *pfi_lds)(long, double, char*) = reinterpret_cast<int (__stdcall *)(long, double, char*)>(aai);
Isn't that just swell? The question is whether it's meaningful.
You're asking how to lie to your compiler. So the first thing to know is: Why do you want to lie?
int a[20][30];
int* b=&a[0][0];
As Steve pointed out, the proper form is int *pTemp = &tempSec[0][0];. int** pTemp2 = tempSec; does not work. The error given is:
cannot convert 'int (*)[3]' to 'int**' in initialization
It's not stored as an array of pointers to arrays. It's stored as one big vector, and the compiler hides the [a][b] = [a*rowLength+b] from you.
#include <iostream>
using namespace std;
int main()
{
// Allocate on stack and initialize.
int tempSec[3][3];
int n = 0;
for(int x = 0; x < 3; ++x)
for(int y = 0; y < 3; ++y)
tempSec[x][y] = n++;
// Print some addresses.
cout << "Array base: " << size_t(tempSec) << endl;
for(int x = 0; x < 3; ++x)
cout << "Row " << x << " base: " << size_t(tempSec[x]) << endl;
// Print contents.
cout << "As a 1-D vector:" << endl;
int *pTemp = &tempSec[0][0];
for(int k = 0; k < 9; ++k)
cout << "pTemp[" << k << "] = " << pTemp[k] << endl;
return 0;
}
Output:
Array base: 140734799802384
Row 0 base: 140734799802384
Row 1 base: 140734799802396
Row 2 base: 140734799802408
As a 1-D vector:
pTemp[0] = 0
pTemp[1] = 1
pTemp[2] = 2
pTemp[3] = 3
pTemp[4] = 4
pTemp[5] = 5
pTemp[6] = 6
pTemp[7] = 7
pTemp[8] = 8
Note that the Row 0 address is the same as the full array address, and consecutive rows are offset by sizeof(int) * 3 = 12.
Another way to go about doing this, is to first create an array of pointers:
int* pa[3] = { temp[0], temp[1], temp[2] };
Then create a pointer pointer to point to that:
int** pp = pa;
You can then use normal array syntax on that pointer pointer to get the element you're looking for:
int x = pp[1][0]; // gets the first element of the second array
Also, if the only reason you're trying to convert it to a pointer is so you can pass it to a function, you can do this:
void f(int v[3][3]);
As long as the size of the arrays are fixed, you can pass a two-dimensional array to a function like this. It's much more specific than passing a pointer.
Original post follows - please disregard, it is misinformed. Leaving it for posterity's sake ;)
However, here is a link I found regarding memory allocation of 2-dimensional arrays in c++. Perhaps it may be of more value.
Not sure it's what you want, and it's been a while since I've written c++, but the reason your cast fails is because you are going from an array of arrays to a pointer of ints. If, on the other hand, you tried from array to array to a pointer of pointers, it would likely work
int tempSec[3][3];
int** pTemp = tempSec;
remember, your array of arrays is really a contiguous block of memory holding pointers to other contiguous blocks of memory - which is why casting an array of arrays to an array of ints will get you an array of what looks like garbage [that garbage is really memory addresses!].
Again, depends on what you want. If you want it in pointer format, pointer of pointers is the way to go. If you want all 9 elements as one contiguous array, you will have to perform a linearization of your double array.
Let's ask cdecl.org to translate your declaration for us:
int tempSec[3][3]
returns
declare tempSec as array 3 of array 3 of int
Ok, so how do we create a pointer to that? Let's ask cdecl again:
declare pTemp as pointer to array 3 of array 3 of int
returns
int (*pTemp)[3][3]
Since we already have the array 3 of array 3 of int, we can just do:
int (*pTemp)[3][3] = &tempSec;
int tempSec[3][3];
int* pTemp = tempSec[0];