copy a memset grid

Hello, how do I fill in a test grid and copy it into the final grid? To test a maximum of grid and keep the one with the most words placed. With a code like this ?

1
2
3
4
5
6
7
8
9
10
char b[] = {1,2,3,4};
char c[4];
memcpy(c, b, sizeof(char)*4);
/*
* c is now...
*
* +-+-+-+-+
* |1|2|3|4|
* +-+-+-+-+
*/


With b my test grid and c my definitive grid.

My original grid has a size of 26 and is declared as follows:
1
2
3
constexpr int GridSize = 26;
char grid[GridSize][GridSize];
memset(grid, '.', sizeof(grid));
Your question is unclear. memset sets memory bytewise, and so for integers, the only thing that 'really' makes sense to do is to zero the memory, making all the ints zero value, or in some rare cases, 255 them, making them all max negative value.

you can do it:
memset(grid, '.', gridsize*gridsize*sizeof(int)); //this would work but each BYTE of the integer is set to '.' not each full integer set to (int)('.') do you understand?

the C memory functions are fast but not used much in C++ as they require precise coding to avoid errors and are not friendly (read: do not use them for those) with classes including stl containers. They are only really useful for simple types in solid blocks of memory; it won't even work if you made grind ** instead of [][] !

if you want grid to have '.' in each full integer, use a loop or one of the stl algorithms if you can find one that fits. I am pretty sure all of can do it using [index] = '.' which returns true, abusing the common error to get the job done, maybe there is a better pick.. like fill_n()
Last edited on
Maybe:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
#include <memory>
using namespace std;

template<typename T, size_t ROWS, size_t COLS>
void print(T (&grid)[ROWS][COLS]) {
    for (size_t r = 0; r < ROWS; ++r) {
        for (size_t c = 0; c < COLS; ++c)
            cout << grid[r][c] << ' ';
        cout << '\n';
    }
}

int main() {
    const size_t Size = 10;

    char grid[Size][Size];
    uninitialized_fill_n(*grid, Size*Size, '.');

    char grid2[Size][Size];
    uninitialized_copy_n(*grid, Size*Size, *grid2);

    print(grid2);
}

Last edited on
Hello, I don't fully understand what you're trying to tell me. But I think I understand the principle. The code I gave as an example is actually usable in C and not in C++? Well for the code proposed by Dutch, I don't know what this line is for:

 
template<typename T, size_t ROWS, size_t COLS>


But I'm going to try and rewrite my code using this code here. Thank you both so much for your help.
it is usable in c++ as well, but it is C code. C++ inherited 'most' of C so you can do things the C way legally, and it will work, but it is generally not the best approach for most things in c++. Memcpy is extremely fast, so you see it in C++ now and then, but it is a low level crude tool that is prone to programmer errors if not used very, very carefully.

Templates for the most part are used to allow you to build things without specifying the types for code re-use or general purpose tools. The c++ standard template library (there is that word again!) which you should use, a LOT, does this all the time: vector<int> x(100); <-- that is a lot like int x[100] except it now has a variety of additional handy tools, for example you can say x = y for 2 vectors, but not 2 C arrays. See how the types go in the <> brackets?

you do not need the template if you are only working with ints. But its nice to have his example.
Last edited on
Hello, okay. So for my idea to make a backup of the best grid in my crossword puzzle of a sentence (http://www.cplusplus.com/forum/general/270089/6/ ) I'd better use Memcpy ? Precautions are for the buffer, right ?
Thanks for the clarification, that's nice.
Last edited on
No. use c++ tools unless you have a compelling reason that you can clearly explain as to why you had to use a C tool here.
That's the reason for this topic, I don't know how to copy a 2-dimensional array in C++, and to save my best rated grid in my program I have to copy an array. But Dutch's code works? I don't understand what you're getting at?
yes, follow Dutch's example. Which does NOT use memcpy / memset :)

if you can use vectors, you can directly assign them. so copying your grid is just
gridcopy = grid;
Are you allowed to do that? If so I can show you.

If you must use arrays instead of vectors, you need to do it with looping or a built in algorithm, this is what Dutch did.

Last edited on
No need to use uninitialized_fill or uninitialized_copy here, plain old fill and copy will do just fine.
No need to use uninitialized_fill or uninitialized_copy here, plain old fill and copy will do just fine.

No doubt. I'm not sure what I was thinking.
Hello, I tried to copy directly with two for loops like I do to display the grid but it doesn't work I think. Then if you have a better solution than Dutch's, I'll give it a try. But for now Dutch's one works! This is for this part of the code (line 45) :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

int main(int argc, char *argv[])
{
	char grid2[Size][Size];
	uninitialized_fill_n(*grid, Size *Size, '.');
	int score = 0;
	std::string word1 = randomword(0);
	unsigned len_word1 = word1.length();
	int pos_word1 = Align(len_word1, GridSize);
	Place(pos_word1, (GridSize / 2), 0, 0, 1, word1);
	fill_grid();

	notation.push_back(words_vect.size());

	//start of a 100 test loop
	for (unsigned int j = 1; j < 100; j++)
	{
		//grid filling

		std::string word1 = randomword(0);
		unsigned len_word1 = word1.length();
		int pos_word1 = Align(len_word1, GridSize);
		Place(pos_word1, (GridSize / 2), 0, 0, 1, word1);
		fill_grid();

		notation.push_back(words_vect.size());

		for (unsigned int k = 0; k < notation.size(); k++)
		{

			if (notation[j] > notation[k])
			{
				score = score + 1;
			}
			else if (notation[j] < notation[k])
			{
				score = score - 2;
			}
		}

		if (score = notation.size())
		{
			char grid2[Size][Size];
                        //I want to make a backup of the best grid by copying the grid in grid2
			uninitialized_copy_n(*grid, Size *Size, *grid2);
			print(grid2);
			std::cout << notation[j] << "\n";
		}
	}
}


But I must be doing things wrong, the program doesn't end properly. ( The double loop with notation [j] and notation [k] for example! )


"gridcopy = grid;
Are you allowed to do that? If so I can show you."


For that, yes I'm allowed, it's a personal project, I don't have a teacher, except for you ! :) I'm willing to have other ideas because I'll be able to use it in other projects, that's for sure !
Last edited on
Maybe something in here will be helpful

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25


using char2d = vector<vector<char> >;  //this is just an alias for the complex type. 

void print(char2d &grid)  //using the alias as the type now, its still really vector vector char
{
    for (size_t r = 0; r < grid.size(); ++r) 
	{
        for (size_t c = 0; c < grid[r].size(); ++c)
            cout << grid[r][c] << ' ';
        cout << '\n';
    }
}

int main() 
{
    //create a grid, 10x15
    char2d grid (10, vector<char>(15)); //rows = 10, cols = 15 here for example
    //fill it with periods, as before: 
    fill(grid.begin(), grid.end(), vector<char>(15, '.' ));
    //make a copy of it, and print the copy. 
    char2d grid2 = grid;
    print(grid2);
}


that fill statement may be poor efficiency, in favor of simple code. I am not sure, and unless you are doing millions of chars in your grid its not a big deal. You can also change the old school loops to range based for loops, but I will let you look that up if you want to use them.

Line 22 is the one you wanted to see: it just uses an assignment operator to copy. Vectors are really classes and define operators; arrays and C constructs are chunks of memory that lack such features so you have all that hands-on stuff. The template <type> stuff and iterators (.begin() etc) are intimidating syntax at first, but once you get used to them, they save a lot of work and make things really nice.

** One last note ... it is possible what you are doing can be done with a 1-d vector of <string> type. Sometimes this is the way to go, and sometimes the 2d array of characters is correct; it depends on what processing you want to do later (the copying is about the same either way).
Last edited on
Okay, I'll test with this code. Okay, I've seen it a few times but I didn't know if it was the right thing to do, but I think this is the chance. If you guys are talking about this:

 
for (auto k : notation) 


instead of this:

 
for (unsigned int k = 0; k < notation.size(); k++)



I'll try ;) thanks again for your help. It's great.
yes, that is a ranged based for loop.
Topic archived. No new replies allowed.