Why does it print out garbage???

So right now i am tasked to print out some ASCII art. I am told to use a Char ** private variable. So I made a 2D dynamic array of pointers with it, with all of the values being of any 'char' i choose. I was also told to make a to_string method which should store the contents of the array in a string and return the string. When I return the string, it prints out fine but at the end of each row, an extra garbage character is printed out. SO my question is, if my code is wrong or i'm not understanding something.

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

//note that C is already a private variable in the class
  Canvas::Canvas(int width, int height)
{
    this->_width=width;
    this->_height=height;

    this->C=new char* [height];

    for(int i=0;i<height;i++)
    {
        C[i]=new char[width];      
    }


    for(int i=0;i<height;i++)
    {
        for(int j=0;j<width;j++)
        {
            C[i][j]='#';
        }
    }
}
 
string Canvas::to_string()
{
    int height=this->_height;
    std::string copy;
    for(int i =0;i<height;i++)
    {
        std::string roasted;
        roasted+=C[i];
        roasted+="\n";            
        copy+=roasted;
    }
    return copy;
}

//and if i try to print out a 4x6 array. Any other array size will also print fine but with the extra garbage at the end of each row :
####└
####└
####└
####└
####└
####└

//why is there an extra character at the end of each row ?
Last edited on
> why is there an extra character at the end of each row ?

Line 32: roasted+=C[i]; engenders undefined behaviour.
The rows do not contain null-terminated C-style strings (there is no null character at the end of C[i]).

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
51
52
53
54
55
56
57
58
#include <iostream>
#include <string>
#include <algorithm>

struct Canvas
{
    Canvas( std::size_t width, std::size_t height ) ;

    // copy, move, assign, destroy

    std::string to_string() const ;

    // ...

    private:

        std::size_t _width ;
        std::size_t _height ;
        char** C ; // I am told to use a Char ** private variable

        static constexpr char default_fill = '#' ;

        char* make_row() const ;// make a row filled with the default_fill character
};

Canvas::Canvas( std::size_t width, std::size_t height )
    : _width(width), _height(height), C( new char* [height] {} )
{
    // note: this is not exception safe
    for( std::size_t i = 0 ; i < _height ; ++i ) C[i] = make_row() ;
}

std::string Canvas::to_string() const
{
    std::string result ;
    for( std::size_t i = 0 ; i < _height ; ++i )
    {
        for( std::size_t j = 0 ; j < _width ; ++j ) result += C[i][j] ;
        // result += { C[i], C[i]+_width } ; // or use this simpler construct
        // (it has the same effect as the line above)

        result += '\n' ;
    }
    return result ;
}

char* Canvas::make_row() const // make a row filled with the default_fill character
{
    char* row = new char[_width] ;
    std::fill( row, row+_width, default_fill ) ;
    return row ;
}

int main()
{
    Canvas c( 15, 9 ) ;
    std::cout << c.to_string() ;
}

http://coliru.stacked-crooked.com/a/483ab753c7bafd1f
The reason is the missing terminating 0 for C.

It is not required if you assign it differently:
1
2
3
4
        std::string roasted(C, C + _width); // NOTE: constructor (7) is used
        //roasted+=C[i]; // NOTE: This requires a terminating 0
        roasted+="\n";            
        copy+=roasted;


See:

http://www.cplusplus.com/reference/string/string/string/
http://www.cplusplus.com/reference/string/string/assign/
when i try to add std::string roasted(C, C + _width); , it gives me a bunch of errors saying i need import. Im only allowed to use the <string> import.
It is actually std::string roasted(C[i], C[i] + _width);
Forgot tht [i]
Yes, thank you. I fixed the problem with your guys help.
Topic archived. No new replies allowed.