How to add chars to 2D array? - c++

My code:
FILE * file;
file = fopen("c://catalog//file.txt", "r");
int m,n; //size of 2d array (m x n)
fscanf(file, "%d", &m);
fscanf(file, "%d", &n);
fclose(file);
printf("Size: %d x %d\n", m, n);
// create 2d array
char **TAB2 = new char*[m];
for (int i = 0; i < m; i++)
char *TAB2 = new char[n];
// display 2d array
for (int i = 0; i < m; i++){
for (int j = 0; j < n; j++)
{
printf("%c ", &TAB2[i][j]);
}
printf("\n");
}
How fill this array with chars or string? for example text = "someting", and for array 3x5 will be:
S o m e t
h i n g ?
? ? ? ? ?
I tried: TAB2[0][0] = 's'; *&TAB2[0][0] = 's'; for one char, and this does'nt work...
Probably I badly use pointers(?). Anyone help me?

The dynamic allocation array is wrong.
char **TAB2 = new char*[m];
for (int i = 0; i < m; ++i)
TAB2[i] = new char[n];
Check this link for help.
You could try this:
#include<iostream>
using namespace std;
int main() {
const int m = 3, n = 5;
char **TAB2 = new char*[m];
for (int i = 0; i < m; ++i)
TAB2[i] = new char[n];
char c;
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
std::cin >> c;
TAB2[i][j] = c;
}
}
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
std::cout << TAB2[i][j];
}
std::cout << "\n";
}
// NEVER FORGET TO FREE YOUR DYNAMIC MEMORY
for(int i = 0; i < m; ++i)
delete [] TAB2[i];
delete [] TAB2;
return 0;
}
Output:
jorje
georg
klouv
jorje
georg
klouv
Important links:
How do I declare a 2d array in C++ using new?
How do I use arrays in C++?

The allocation of the array seems incorrect; it should be as follows.
char **TAB2 = new char*[m];
for (int i = 0; i < m; i++)
TAB2[i] = new char[n];

Related

C++ string dynamic 2D array cause memory leak

When I use a string type dynamic 2D array, there is memory leak after deleting the array.
Please view the following code:
#include <string>
using namespace std;
#define NEW2D(H, W, TYPE) (TYPE **)new2d(H, W, sizeof(TYPE))
void* new2d(int h, int w, int size)
{
register int i;
void **p;
p = (void**)new char[h*sizeof(void*) + h*w*size];
for(i = 0; i < h; i++)
{
p[i] = ((char *)(p + h)) + i*w*size;
}
return p;
}
If I use the following code:
string** pstr = NEW2D(2, 4, string);
memset(pstr[0], 0, sizeof(string)*2*4);
delete [] pstr;
There is no memory leak; however, if I use the following code:
string** pstr = NEW2D(2, 4, string);
memset(pstr[0], 0, sizeof(string)*2*4);
for (int j = 0; j < 2; j++)
for (int i = 0; i < 4; i++)
pstr[j][i] = "test";
for (int j = 0; j < 2; j++)
for (int i = 0; i < 4; i++)
pstr[j][i].clear();
delete [] pstr;
The memory leak is happened, even if I have called pstr[j][i].clear().
What should I do to avoid memory leak after having
for (int j = 0; j < 2; j++)
for (int i = 0; i < 4; i++)
pstr[j][i] = "test";
in my code?
The problem with your code because it treats non-trivial types like std::string as if they were trivial. Probably you could create something using placement new that was legal C++ and worked in a similar way to the code you've written
But here's an simple alternative that (hopefully) works
template <typename T>
T** new2d(int h, int w)
{
T** p = new T*[h];
T* q = new T[h*w];
for (int i = 0; i < h; i++)
p[i] = q + i*w;
return p;
}
And to delete
template <typename T>
void free2d(T** p, int h)
{
if (h > 0)
delete[] p[0];
delete[] p;
}
Untested code.
Thanks to John. I have tried the following code, it works well:
int i;
int data_height = 2, data_width = 4;
string **data;
data = new string*[data_height];
for(i = 0; i < data_height; i++)
data[i] = new string[data_width];
for (int j = 0; j < 2; j++)
for (int i = 0; i < 4; i++)
data[j][i] = "test";
for(i = 0; i < data_height; i++)
delete [] data[i];
delete [] data;

Assign pointer to 2d array to an array

So I got a function which creates me 2D array and fill it with test data.
Now I need to assign the pointer to an array
//Fill matrix with test data
int *testArrData(int m, int n){
int arr[n][m];
int* ptr;
ptr = &arr[0][0];
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
*((ptr+i*n)+j) = rand()%10;
}
}
return (int *) arr;
}
int arr[m][n];
//Algorithm - transpose
for (int i = 0; i < m; i++){
for (int j = 0; j < n; j++){
arrT[j][i] = arr[i][j];
}
}
Is there any way of doing this?
There are at least four problems with the function.
//Fill matrix with test data
int *testArrData(int m, int n){
int arr[n][m];
int* ptr;
ptr = &arr[0][0];
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
*((ptr+i*n)+j) = rand()%10;
}
}
return (int *) arr;
}
First of all you declared a variable length array
int arr[n][m];
Variable length arrays are not a standard C++ feature.
The second problem is that these for loops
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
*((ptr+i*n)+j) = rand()%10;
}
}
are incorrect. It seems you mean
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
*((ptr+i*m)+j) = rand()%10;
}
}
You are returning a pointer to a local array with automatic storage duration that will not be alive after exiting the function. So the returned pointer will be invalid.
And arrays do not have the assignment operator.
Instead use the vector std::vector<std::vector<int>>. For example
std::vector<std::vector<int>> testArrData(int m, int n){
std::vector<std::vector<int>> v( n, std::vector<int>( m ) );
for ( auto &row : v )
{
for ( auto &item : row )
{
item = rand() % 10;
}
}
return v;
}
This is how I would accomplish this. I agree with int ** because it is easy to understand if you dont know how to use vectors. Also, the rand() can cause trouble if you are using the result to index an array. Make sure to use abs(rand() % number) if you don't want negative numbers.
I've updated the answer due to some vital missing code.
// This method creates the overhead / an array of pointers for each matrix
typedef int* matrix_cells;
int **create_row_col_matrix(int num_rows, int num_cols, bool init_rnd)
{
num_rows = min(max(num_rows, 1), 1000); // ensure num_rows = 1 - 1000
num_cols = min(max(num_cols, 1), 1000); // ensure num_cols = 1 - 1000
int *matrix_total = new int[num_rows*num_cols];
// overhead: create an array that points to each row
int **martix_row_col = new matrix_cells[num_rows];
// initialize the row pointers
for (int a = 0; a < num_rows; ++a)
{
// initialize the array of row pointers
matrix_row_col[a] = &matrix_total[num_cols*a];
}
// assign the test data
if (init_rnd)
{
for (int run_y = 0; run_y < num_rows; ++run_y)
{
for (int run_x = 0; run_x < num_cols; ++run_x)
{
matrix_row_col[run_y][run_x] = abs(rand() % 10);
}
}
}
return matrix_row_col;
}
int src_x = 7, dst_x = 11;
int src_y = 11, dst_y = 7;
int **arr_src = create_row_col_matrix(src_y, src_x, true);
int **arr_dst = create_row_col_matrix(dst_y, dst_x, false);
for (int a = 0; a < dst_y; ++a)
{
for (int b = 0; b < dst_x; ++b)
{
arr_dst[a][b] = arr_src[b][a];
}
}
delete matrix_src[0]; // int *matrix_total = new int[src_y*src_x]
delete matrix_src; // int **matrix_row_col = new matrix_cell[src_y]
delete matrix_dst[0]; // int *matrix_total = new int[dst_y*dst_x]
delete matrix_dst; // int **matrix_row_col = new matrix_cell[dst_y]
// the overhead is matrix_src and matrix_dst which are arrays of row pointers
// the row pointers makes it convenient to address the cells as [rown][coln]

corrupted size vs. prev_size in c++.Double pointer problem

(I am new at C++)
Currently I am using double pointers to read a file which reads the size of the matrix, but when I read a new file with a diferent size of the last one corrupted size vs. prev_size pops up. I guess the problem is because
I read the file here:
SolucioU::SolucioU(string fitxer, int costM, int difM)
{
ifstream f(fitxer);
int x, y;
int edificis, valor;
bool trobat = false;
Posicio p, ini;
int i = 0;
costMax = costM;
difMax = difM;
if (not f.is_open()) throw ("El fitxer no es pot obrir.Revisa el nom o els permisos. ");
f >> midax >> miday;
reserva();
for (int i = 0; i < midax; i++) {
for (int j = 0; j < miday; j++) {
f >> matriu[i][j];
usat[i][j] = false;
edifici[i][j] = 0;
}
}
f >> x >> y;
recorregut.push_back(Posicio(x, y));
usat[x][y] = true;
cost = 10;
dif = matriu[x][y];
f >> edificis;
if (edificis != 0) {
for (int k = 0; k < edificis; k++) {
f >> x >> y >> valor;
edifici[x][y] = valor;
}
}
f.close();
}
I guess the problem can be here, where i declare the size of the pointers.
void SolucioU::reserva(){
matriu = new int* [midax - 1];
for (int i = 0; i < midax; i++)
matriu[i] = new int[miday + 1];
usat = new bool* [midax - 1];
for (int i = 0; i < midax; i++)
usat[i] = new bool[miday + 1];
edifici = new int* [midax - 1];
for (int i = 0; i < midax; i++)
edifici[i] = new int[miday + 1];
}
I will try to give You a snippet that should help You with this problem.
// Somewhere in the code:
std::vector<std::vector<int>> matriu;
std::vector<std::vector<int>> usat;
std::vector<std::vector<int>> edifici;
//
void reserva(){
matriu = {};
matriu.reserve(midax);
for (int i = 0; i < midax; i++)
matriu.push_back(std::vector<int>(miday + 1, 0));
usat = {};
usat.reserve(midax);
for (int i = 0; i < midax; i++)
usat.push_back(std::vector<int>(miday + 1, 0));
edifici = {};
edifici.reserve(midax);
for (int i = 0; i < midax; i++)
edifici.push_back(std::vector<int>(miday + 1, 0));
}
A few advices:
As I wrote in the comment - try avoid using new as much as possible. It's very bug-prone. Use structures or smart pointers to avoid memory leak.
If You need to use new[], ensure that there is a corresponding delete[].
Try to code in english, it will be easier to share Your code with other people.

dynamic array in c++

I need to implement a 5x5 dynamic array where
every element in it is equal to the sum of its two indices. For example, the first element, at (0,0), has the value 0+0=0.
Here is my code:
# include<iostream>
using namespace std;
int main()
{
int size =5;
int *array=new int[size];
for (int i = 0; i < size; i++)
delete [] array;
return 0;
}
I need help to implement sum of index.
You need at first to implement a two-dimensional array.:)
Here you are.
#include <iostream>
int main()
{
const size_t N = 5;
int ( *array )[N] = new int[N][N];
for ( size_t i = 0; i < N; i++ )
{
for ( size_t j = 0; j < N; j++ ) array[i][j] = i + j;
}
for ( size_t i = 0; i < N; i++ )
{
for ( size_t j = 0; j < N; j++ ) std::cout << array[i][j] << ' ';
std::cout << std::endl;
}
delete [] array;
return 0;
}
And do not pay attention that the answer is down voted. There is nothing wrong with the answer. :)
Firstly, you should create a 2d-array, not just a array.
void foo() {
int **a = new int*[5];
for (int i = 0; i < 5; i++)
a[i] = new int[5];
}
for (int i = 0; i < 5; i++)
for (int j = 0; j < 5; j++)
a[i][j] = i + j;
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++)
cout << a[i][j] << " ";
cout << endl;
}
for (int i = 0; i < 5; i++)
delete[] a[i];
delete[] a;
}
And, of course, don't forget to clear your memory)

C++ 2D dynamic array allocation

I have a float** array that contains num_rows rows and num_cols columns. I'd like to determine the number of occurrences of every number between 0-9 columnwise. To do this, I thought of using another 2D array of size [10][num_cols], so that for each column the number corresponding to an element is the number of occurrences of that number in the original table.
Example: if the original table contains 1 2 3 1 1 in the fifth column, then in the second column, the values should be like: 1-> 3, 2 -> 1, 3 -> 1.
I tried using the function as follows, but it gives me a pointer error. I tried using vectors but that too brings no luck.
int ** attribute_count(float * * input, int row_num, int col_num) {
int ** arr_2 = new int * [10];
int * arr = new int[10 * col_num];
int counter = 0;
for (int i = 0; i < 9; i++) {
for (int j = 0; j < col_num; j++) {
arr_2[i][j] = 0;
}
}
for (int i = 0; i < 9; i++) {
for (int j = 0; j < col_num; j++) {
int temp = input[i][j];
arr_2[temp][j]++;
}
}
return arr_2;
}
EDIT:
I tried your suggestions. The new code is:
int** attribute_count(float** input, int row_num, int col_num) {
int** arr_2 = new int* [10];
int* arr = new int[10 * col_num];
int counter = 0;
for (int i = 0; i < 11; i++) {
for (int j = 0; j < col_num; j++) {
arr_2[i] = new int[col_num];
}
}
for (int i = 0; i < 11; i++) {
for (int j = 0; j < col_num; j++) {
int temp = input[i][j];
arr_2[temp][j]++;
}
}
return arr_2;
}
This still gives me memory errors. The function is being called in the .cpp like this:
int** attr = attribute_count(training_data, 10, num_cols_train);
cout<<attr[5][1];
Any idea what I'm doing wrong even now?
I think your problem is in incorrect allocation of the 2D array. Try
int ** arr_2 = new int* [row_num];
for (int i = 0; i < row_num; i++)
arr_2[i] = new int[col_num];
You've only allocated one dimension of arr_2. You need to loop through and allocate an array of ints on each one to get the 2nd dimension.
EDIT: Also, what's up with arr? You allocate it, never use it, don't return it, and don't deallocate it. That's how we spell memory leak.
arr_2 is defined and allocated as an array of pointers to int, but you don't actually assign/allocate those pointers.
Here's a stab at correcting your code - however I'm not convinced you have rows and columns the right way around...
int ** attribute_count(float ** input, int row_num, int col_num)
{
int ** arr_2 = new int * [10];
for (int i = 0; i < 10; i++)
{
arr_2[i] = new int[col_num];
for(int j = 0 ; j < col_num ; j++)
{
arr_2[i][j] = 0;
}
}
for (int i = 0; i < row_num; i++)
{
for (int j = 0; j < col_num; j++)
{
int temp = input[i][j];
arr_2[temp][j]++;
}
}
return arr_2;
}