initializing a multi dimensional array c++ - c++

I am working in VC++ 2008, and am trying to allocate a multi-dimensional array of chars to do some file work. I know that whenever an array is allocated all the members of the array should be initialized usually in a successive order. what I have currently is this.
char ** thing = new char *[lineY];
for (int ii = 0; ii < lineY; ii++){
thing[ii] = new char[lineX];
}
... // working with array
// deleting each part of the array.
for (int ii = 0; ii < lineY; ii++){
delete [] thing[ii];
}
delete [] thing;
the problem that I am running into is that if I add the array to the watch list, or put a break right after its been allocated the debugger states that the array is equal to a number like 51, or 32, and not a block of space with indexes, and values, but when I try to initialize the values of each index by making my allocation this:
char ** thing = new char *[lineY];
for (int ii = 0; ii < lineY; ii++){
thing[ii] = new char[lineX];
for (int jj = 0; jj < lineX; jj++){
thing[ii][jj] = '';
}
}
edit: the compiler throws "C2137 empty character constant" am I doing something wrong?
edit: read msdn on the error number, and found answer

You cannot write thing[ii][jj] = '' because '' is an empty character constant which isn't allowed. Try replacing '' with something like ' ' (with the space between 's)

Are lineX and lineY compile-time constants? In that case:
std::array<std::array<char, lineX>, lineY> thing;
Otherwise:
std::vector<std::vector<char> > thing(lineY, std::vector<char>(lineX));

Related

How to return 2D Array without causing Segmentation Fault (C++)

A homework assignment for an introductory C++ course.
The task is to search a two dimensional array for two numbers adding up to a given number 'search_sum.' Enter all found addends as {startRow,startColumn,endRow,endColumn} in the array 'summations,' then return the array 'summations'.
The line with summations[*sums_found] = new size_t[kIndices_size]; in the if statement was written by the instructor, as well as the comment. I am under the impression that this allocates a new space in memory where data can be assigned to and stored, so, in the next line of code, I attempted to take the column and row variables from the for loop and place them in the newly allocated memory as such.
summations[*sums_found]={startRow, column, endRow, column};
This threw a 'too many assignments' and 'segmentation fault' error.
I assumed you just could not do it this way, and data must be added to a 2D array in another fashion. I removed the faulty assignment code and ran the code as shown below through a debugger, just out of curiosity. The error thrown was once again a Segmentation Fault.
// Parameters:
// - matrix: a two-dimension integer array
// - matrix_size: a two-element size_t array storing sizes of matrix
// - search_sum: the integer value for which the function seeks sums
// - sums_found: an OUTPUT PARAMETER pointing to a size_t
//
const size_t** FindSum(const int** matrix,
const size_t* matrix_size,
int search_sum,
size_t* sums_found) {
*sums_found = 0; // init sums found to 0
size_t summations_size = 2; // start assuming no more than 2 summations
// build structure to hold all found summations
size_t** summations = new size_t*[summations_size];
switch (search_sum)
{
case -92:{ //column search
for(size_t column = 0; column < matrix_size[1]; column++){
for(size_t startRow = 0; startRow < matrix_size[0]; startRow++){
for(size_t endRow = 0; endRow < matrix_size[0]; endRow++){
int j = matrix[startRow][column];
int k = matrix[endRow][column];
int sum = j + k;
if(sum = search_sum){
summations[*sums_found] = new size_t[kIndices_size]; // only done when summation is found
*sums_found++;
}
}
}
}
}
break;
case 60:{ //row search
for(size_t row = 0; row < matrix_size[0]; row++){
for(size_t startColumn = 0; startColumn < matrix_size[1]; startColumn++){
for(size_t endColumn = 0; endColumn < matrix_size[1]; endColumn++){
int j = matrix[row][startColumn];
int k = matrix[row][endColumn];
int sum = j + k;
if(sum = search_sum){
summations[*sums_found] = new size_t[kIndices_size]; // only done when summation is found
*sums_found++;
}
}
}
}
}
break;
case 1203:{ //desc/ascending diagonal
}
break;
case 412:{ //single entry
}
break;
default:{ //large array
}
break;
}
return const_cast<const size_t**>(summations);
}
I did not know what this was, so I researched the error and found that you are not allowed to perform a read/write action on read-only code, which makes sense. What I do not understand is what exactly makes this code read-only, when it seems like its function is to assign a new space for data to be assigned to, which (to me), sounds like a 'write-like' action? I more than likely am misunderstanding the full scope of the codes function, and I am further confused with as to how I should go about assigning the data to the summations array.
Also, this is a university course taught by a grad student who is (seemingly) less than well versed in c++. It is a very 'teach yourself' type class. I understand that this assignment is an exercise on pointers and references, but it feels like I am very poorly equipped to solve a problem like this, and I am unsure what exactly to research and study independently to improve my knowledge of this particular topic. Please, if you can tell what it is I am struggling with just by looking at the code I've written, let me know what I should prioritize my studying on.

Pushing back a vector of strings into a 2D vector

I am currently working in C++, dealing with string vectors.
Let's say I have a 1D string vector called 'temp.' At each index of 'temp', there is a string containing three words/chars. Let's say that temp[0] = "Hello hi 3"
I have defined a function called 'splits' which takes in some string, and removes the whitespaces, and places the result in a string vector called 'res'. So, using the 'splits' function on temp[0] results in:
res[0] = hello
res[1] = hi
res[2] = 3
I would like to use the "splits" function on each string held in 'links,' and pass it into a 2d vector of strings called 'totalResults.' As I do not know the size of 'links' I know that I will need to dynamically allocate this 2D vector of strings.
So far I have:
vector<vector<string>> totalResults //dynamically allocated 2d vector of strings
vector<string> temp;
for (int i = 0; i<rows; i++)
{
for (int j = 0; j<cols; j++)
{
temp=splits(links[j])
totalResults[i][j].push_back(temp[0][j]));
//using splitting function on links[i], and pushing it into the 2d vector
}
}
In this example, I would like "hello" to go into totalResults[0][0], "hi" to go into totalResults[0][1], and "3" to go into totalResults[0][2].
In the second row of totalResults, I would like the same assignment to occur, but when 'splits' is used on 'links[1]'.
I have testing the 'splits' function in isolation, and it works as I expect it to, so I am assuming the error may be in how I am pushing back values into this 2d vector. I am testing the resulting 2D matrix, but nothing is printing... Are the values not actually being pushed in?
I appreciate any help/ideas!
Thank you! :)
Based on your description, links has cols elements, and you want to split each links[j] and add it to totalResults:
vector<vector<string>> totalResults(cols);
for (int j = 0; j < cols; j++)
{
totalResults[j] = splits(links[j]);
}

Dynamically allocating a 2D array of object pointers in a class

I'm struggling at the moment with the idea of dynamically allocating arrays at runtime. Coming from Java, used to just declaring the arrays in the class skeleton and only needing the size in the implementation.
This is what I've found to dynamically allocate 2D arrays:
Grid.h
Block** grid;
Grid.cpp
grid = new Block*[size]
for(int i = 0 ; i < size ; i++)
grid[i] = new Block[size]
This works pretty okay, although dealing with objects I've always been told that using pointers to objects rather than storing the objects themselves is much better performance wise. So when I tried to make the second dimension of arrays pointers like this:
Grid.cpp
grid = new Block*[size]
for(int i = 0 ; i < size ; i++)
grid[i] = new Block*[size];
When I changed my code to this, I got an error:
error: assigning to 'Block *' from incompatible type 'Block **'; dereference with *
grid[i] = new Block* [size];
^ ~~~~~~~~~~~~~~~~~
*
Being slightly new to the C++ ways of doing things, can someone tell me what I'm doing wrong? Or even if I'm trying to do the wrong thing entirely?
Thanks in advance!
I would not recommend you writing this type of code, but if you still want to hack your way out you can do something like this:-
int main()
{
Block*** grid;
grid = new Block**[10];
for(int i = 0 ; i < 10 ; i++)
{
grid[i] = new Block*[10];
}
/*Here, we have created a grid of pointers*/
/*
|Block**[10]|
|Block[0] **|------------->|Block* [10]|
|Block[1] **|------------->|Block* [10]|
|Block[2] **|------------->|Block* [10]|
|Block[3] **|------------->|Block* [10]|
..
..
|Block[9] **|------------->|Block* [10]|
*/
for(int i = 0 ; i < 10 ; i++)
{
for(int j = 0 ; j < 10 ; j++)
{
grid[i][j] = new Block[10];
}
}
/*
|Block**[10]|
|Block[0] **|------------->|Block* [0]|------------->|Block1|Block2| .. |Block10|
|Block* [1]|------------->|Block1|Block2| .. |Block10|
|Block* [2]|------------->|Block1|Block2| .. |Block10|
..
|Block* [9]|------------->|Block1|Block2| .. |Block10|
|Block[1] **|------------->|Block* [0]|------------->|Block1|Block2| .. |Block10|
|Block* [1]|------------->|Block1|Block2| .. |Block10|
|Block* [2]|------------->|Block1|Block2| .. |Block10|
..
|Block* [9]|------------->|Block1|Block2| .. |Block10|
|Block[2] **|
|Block[3] **|
..
..
|Block[9] **|
*/
}
A dynamic 2D array is an array of pointers to arrays.
You should initialize first the array of pointer, then the others array using a loop.
Here an example using int that creates an array[rowCount][colCount]:
int** array = new int*[rowCount];
for(int i = 0; i < rowCount; ++i)
array[i] = new int[colCount];
otherwise of course you can always have a 2D array on the stack by using:
int array[rowCount][colCount];
Use a linear representation of 2d array:
std::unique_ptr<int[]> array(new int[rowCount*colCount]);
for (size_t r = 0; r < rowCount; r++)
for (size_t c = 0; c < colCount; c++)
(array.get())[r*colCount + c] = r*c;
Alocating array of pointers can also be done in thread safe manner:
size_t allocatedRows = rowCount;
try{
array = new char*[allocatedRows];
while(allocatedRows){
--allocatedRows;
array[allocatedRows] = new char[colCount];
}
}catch(std::bad_alloc& ex){
while(++allocatedRows < lines)
delete array[allocatedRows];
delete array;
throw;
}
Two thing to note in code above:
1) allocatedRows is not decremented in [] operator, as behaviour would be undefined
2) After allocating array of pointers, dereferencing array elemnts has undefined behaviour(just like normal pointer without assignment).
Please also keep in mind that in case above I didn't recovered from bad_alloc I just rethrowed, It can be logged somewhere else before call to termination. If You would like to create array of pointers from other user defined objects You could use std::uninitialized_copy or std::uninitialized_fill.
Another way would be just to use vectors.

Trying to fill a 2d array of structures in C++

As above, I'm trying to create and then fill an array of structures with some starting data to then write to/read from.
I'm still writing the cache simulator as per my previous question:
Any way to get rid of the null character at the end of an istream get?
Here's how I'm making the array:
struct cacheline
{
string data;
string tag;
bool valid;
bool dirty;
};
cacheline **AllocateDynamicArray( int nRows, int nCols)
{
cacheline **dynamicArray;
dynamicArray = new cacheline*[nRows];
for( int i = 0 ; i < nRows ; i++ )
dynamicArray[i] = new cacheline [nCols];
return dynamicArray;
}
I'm calling this from main:
cacheline **cache = AllocateDynamicArray(nooflines,noofways);
It seems to create the array ok, but when I try to fill it I get memory errors, here's how I'm trying to do it:
int fillcache(cacheline **cache, int cachesize, int cachelinelength, int ways)
{
for (int j = 0; j < ways; j++)
{
for (int i = 0; i < cachesize/(cachelinelength*4); i++)
{
cache[i][ways].data = "EMPTY";
cache[i][ways].tag = "";
cache[i][ways].valid = 0;
cache[i][ways].dirty = 0;
}
}
return(1);
}
Calling it with:
fillcache(cache, cachesize, cachelinelength, noofways);
Now, this is the first time I've really tried to use dynamic arrays, so it's entirely possible I'm doing that completely wrong, let alone when trying to make it 2d, any ideas would be greatly appreciated :)
Also, is there an easier way to do write to/read from the array? At the moment (I think) I'm having to pass lots of variables to and from functions, including the array (or a pointer to the array?) each time which doesn't seem efficient?
Something else I'm unsure of, when I pass the array (pointer?) and edit the array, when I go back out of the function, will the array still be edited?
Thanks
Edit:
Just noticed a monumentally stupid error, it should ofcourse be:
cache[i][j].data = "EMPTY";
You should find your happiness. You just need the time to check it out (:
The way to happiness

Radix Sort using C++

Suppose I have bunch of numbers. I have to first put the least significant digit into the corresponding bucket. Ex: 530 , I have to first put into the bucket 0. For number 61, I have to put into bucket 1.
I planned to use a multidimensional array to do this. So I create a 2-dimenional array, which nrows is 10 ( for 0~ 9) and ncolumns is 999999 ( because I don't know how large will the list be):
int nrows = 10;
int ncolumns = 999999;
int **array_for_bucket = (int **)malloc(nrows * sizeof(int *));
for(i = 0; i < nrows; i++)
array_for_bucket[i] = (int *)malloc(ncolumns * sizeof(int));
left = (a->value)%10;
array_for_bucket[left][?? ] = a->value;
Then I created one node call a. In this node a, there is a value 50. To find out which bucket I want to put it in, I calculate "left" and I got 0. So I want to put this a-> value into bucket 0. But now I am stuck. How do I put this value into the bucket? I have to use a pointer array to do this.
I thought for a long time but still couldn't find a good way to do it. So please share some ideas with me. thank you!
There is a much easier way of doing this, and instead of radix*nkeys space you only need an nkeys-sized buffer.
Allocate a second buffer that can fit nkeys keys. Now do a first pass through your data and simply count how many keys end up in each bucket. You now can create a radix-sized array of pointers where each pointer is to the start of that bucket in the output buffer. Finally, the second pass though the data moves the keys. Every time you move a key, increment that bucket pointer.
Here's some C code to make into C++:
void radix_sort(int *keys, int nkeys)
{
int *shadow = malloc(nkeys * sizeof(*keys));
int bucket_count[10];
int *bucket_ptrs[10];
int i;
for (i = 0; i < 10; i++)
bucket_count[i] = 0;
for (i = 0; i < nkeys; i++)
bucket_count[keys[i] % 10]++;
bucket_ptrs[0] = shadow;
for (i = 1; i < 10; i++)
bucket_ptrs[i] = bucket_ptrs[i-1] + bucket_count[i-1];
for (i = 0; i < nkeys; i++)
*(bucket_ptrs[keys[i] % 10]++) = keys[i];
//shadow now has the sorted keys
free(shadow);
}
But I may have misunderstood the question. If you are doing something a little different than radix sort, pleas add some details.
Look the Boost Pointer containers library if you want to store pointers.
C++ isn't my forte but this code from wikipedia-Raidx Sort is very comprehensive and probably is more C++-ish than what you've implemented so far. Hope it helps
This is C++, we don't use malloc anymore. We use containers. A two-dimensional array is a vector of vectors.
vector<vector<int> > bucket(10);
left = (a->value)%10;
bucket[left].push_back(a->value);