Thread: Printing string bigger than the maximum size

  1. #1
    Tears of the stars thames's Avatar
    Join Date
    Oct 2012
    Location
    Rio, Brazil
    Posts
    193

    Question Printing string bigger than the maximum size

    Good evening. Why was possible to print a string with 14 bytes when I just allocated 6 bytes for it ?

    Code:
     
    #include <iostream> 
    #include <cstring> 
    
    using namespace std; 
    
    const int MAXSIZE = 20; 
    
    int main(void) 
    { 
        char name[MAXSIZE]; 
        char lastName[MAXSIZE]; 
        
        
        cout << "Enter your first name: "; 
        cin.get(name, MAXSIZE).get();
        cout << "Enter your last name: "; 
        cin.get(lastName, MAXSIZE).get();
        
        // lastName, name\0
        char *fullName = new char[strlen(name)]; 
        
        strcpy(fullName, lastName); 
        strcat(fullName, ", ");
        strcat(fullName, name); 
        
        cout << "Here's the information in a single string: " << fullName << endl; 
        
        delete fullName; 
        return 0;     
    }
    Code:
     
    thames@semaht ~/C++/Strings $ g++ -g -Wall personinfo2.cpp -o personinfo2
    thames@semaht ~/C++/Strings $ gdb -q personinfo2
    Lendo símbolos de /home/thames/C++/Strings/personinfo2...concluído.
    (gdb) break 26
    Ponto de parada 1 at 0x400cd2: file personinfo2.cpp, line 26.
    (gdb) r
    Starting program: /home/thames/C++/Strings/personinfo2 
    Enter your first name: thames
    Enter your last name: thames
    
    Breakpoint 1, main () at personinfo2.cpp:26
    26        cout << "Here's the information in a single string: " << fullName << endl; 
    (gdb) print fullName
    $1 = 0x603010 "thames, thames"
    (gdb) print strlen(fullName)
    $2 = 14
    (gdb) print strlen(name)
    $3 = 6
    (gdb) c
    Continuando.
    Here's the information in a single string: thames, thames
    [Inferior 1 (process 2738) exited normally]
    (gdb)
    Last edited by thames; 12-13-2012 at 03:44 PM.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    It's "possible", because it's all down to pure dumb luck.

    Using a different tool to test your program, and you see there is much to complain about.
    Code:
    $ valgrind ./a.out
    ==3136== Memcheck, a memory error detector
    ==3136== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
    ==3136== Using Valgrind-3.6.1-Debian and LibVEX; rerun with -h for copyright info
    ==3136== Command: ./a.out
    ==3136== 
    Enter your first name: Commander
    Enter your last name: Z
    ==3136== Invalid write of size 1
    ==3136==    at 0x4C29484: strcat (mc_replace_strmem.c:176)
    ==3136==    by 0x400B56: main (in /home/sc/Documents/a.out)
    ==3136==  Address 0x5973049 is 0 bytes after a block of size 9 alloc'd
    ==3136==    at 0x4C2864B: operator new[](unsigned long) (vg_replace_malloc.c:305)
    ==3136==    by 0x400AF8: main (in /home/sc/Documents/a.out)
    ==3136== 
    ==3136== Invalid write of size 1
    ==3136==    at 0x4C29493: strcat (mc_replace_strmem.c:176)
    ==3136==    by 0x400B56: main (in /home/sc/Documents/a.out)
    ==3136==  Address 0x597304a is 1 bytes after a block of size 9 alloc'd
    ==3136==    at 0x4C2864B: operator new[](unsigned long) (vg_replace_malloc.c:305)
    ==3136==    by 0x400AF8: main (in /home/sc/Documents/a.out)
    ==3136== 
    ==3136== Invalid write of size 1
    ==3136==    at 0x4C29495: strcat (mc_replace_strmem.c:176)
    ==3136==    by 0x400B56: main (in /home/sc/Documents/a.out)
    ==3136==  Address 0x597304c is 3 bytes after a block of size 9 alloc'd
    ==3136==    at 0x4C2864B: operator new[](unsigned long) (vg_replace_malloc.c:305)
    ==3136==    by 0x400AF8: main (in /home/sc/Documents/a.out)
    ==3136== 
    ==3136== Invalid read of size 1
    ==3136==    at 0x4C29727: strlen (mc_replace_strmem.c:282)
    ==3136==    by 0x4EC7800: std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16)
    ==3136==    by 0x400B74: main (in /home/sc/Documents/a.out)
    ==3136==  Address 0x5973049 is 0 bytes after a block of size 9 alloc'd
    ==3136==    at 0x4C2864B: operator new[](unsigned long) (vg_replace_malloc.c:305)
    ==3136==    by 0x400AF8: main (in /home/sc/Documents/a.out)
    ==3136== 
    ==3136== Invalid read of size 1
    ==3136==    at 0x51AC2B4: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1317)
    ==3136==    by 0x51A1F9C: fwrite (iofwrite.c:45)
    ==3136==    by 0x4EC7574: std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16)
    ==3136==    by 0x4EC780E: std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16)
    ==3136==    by 0x400B74: main (in /home/sc/Documents/a.out)
    ==3136==  Address 0x597304b is 2 bytes after a block of size 9 alloc'd
    ==3136==    at 0x4C2864B: operator new[](unsigned long) (vg_replace_malloc.c:305)
    ==3136==    by 0x400AF8: main (in /home/sc/Documents/a.out)
    ==3136== 
    ==3136== Invalid read of size 1
    ==3136==    at 0x51AC2C9: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1317)
    ==3136==    by 0x51A1F9C: fwrite (iofwrite.c:45)
    ==3136==    by 0x4EC7574: std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16)
    ==3136==    by 0x4EC780E: std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16)
    ==3136==    by 0x400B74: main (in /home/sc/Documents/a.out)
    ==3136==  Address 0x597304a is 1 bytes after a block of size 9 alloc'd
    ==3136==    at 0x4C2864B: operator new[](unsigned long) (vg_replace_malloc.c:305)
    ==3136==    by 0x400AF8: main (in /home/sc/Documents/a.out)
    ==3136== 
    ==3136== Invalid read of size 1
    ==3136==    at 0x51AC230: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1349)
    ==3136==    by 0x51A1F9C: fwrite (iofwrite.c:45)
    ==3136==    by 0x4EC7574: std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16)
    ==3136==    by 0x4EC780E: std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16)
    ==3136==    by 0x400B74: main (in /home/sc/Documents/a.out)
    ==3136==  Address 0x5973049 is 0 bytes after a block of size 9 alloc'd
    ==3136==    at 0x4C2864B: operator new[](unsigned long) (vg_replace_malloc.c:305)
    ==3136==    by 0x400AF8: main (in /home/sc/Documents/a.out)
    ==3136== 
    ==3136== Invalid read of size 1
    ==3136==    at 0x51AC23E: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1348)
    ==3136==    by 0x51A1F9C: fwrite (iofwrite.c:45)
    ==3136==    by 0x4EC7574: std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16)
    ==3136==    by 0x4EC780E: std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16)
    ==3136==    by 0x400B74: main (in /home/sc/Documents/a.out)
    ==3136==  Address 0x597304a is 1 bytes after a block of size 9 alloc'd
    ==3136==    at 0x4C2864B: operator new[](unsigned long) (vg_replace_malloc.c:305)
    ==3136==    by 0x400AF8: main (in /home/sc/Documents/a.out)
    ==3136== 
    Here's the information in a single string: Z, Commander
    ==3136== Mismatched free() / delete / delete []
    ==3136==    at 0x4C27FF2: operator delete(void*) (vg_replace_malloc.c:387)
    ==3136==    by 0x400B8D: main (in /home/sc/Documents/a.out)
    ==3136==  Address 0x5973040 is 0 bytes inside a block of size 9 alloc'd
    ==3136==    at 0x4C2864B: operator new[](unsigned long) (vg_replace_malloc.c:305)
    ==3136==    by 0x400AF8: main (in /home/sc/Documents/a.out)
    ==3136== 
    ==3136== 
    ==3136== HEAP SUMMARY:
    ==3136==     in use at exit: 0 bytes in 0 blocks
    ==3136==   total heap usage: 1 allocs, 1 frees, 9 bytes allocated
    ==3136== 
    ==3136== All heap blocks were freed -- no leaks are possible
    ==3136== 
    ==3136== For counts of detected and suppressed errors, rerun with: -v
    ==3136== ERROR SUMMARY: 15 errors from 9 contexts (suppressed: 4 from 4)
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Tears of the stars thames's Avatar
    Join Date
    Oct 2012
    Location
    Rio, Brazil
    Posts
    193
    edit:

    ah, nevermind.

    Code:
     delete [] fullname;
    many thanks. Valgrind is a damn freaking cool tool.

    I forgot to use Valgrind

    edit:

    Code:
     
    #include <iostream> 
    #include <cstring> 
    
    using namespace std; 
    
    const int MAXSIZE = 20; 
    
    int main(void) 
    { 
        char name[MAXSIZE]; 
        char lastName[MAXSIZE]; 
        
        cout << "Enter your first name: "; 
        cin.get(name, MAXSIZE).get();
        cout << "Enter your last name: "; 
        cin.get(lastName, MAXSIZE).get();
        
        // lastName, name\0
        char *fullName = new char[strlen(name) + strlen(lastName) + 3]; 
        
        strcpy(fullName, lastName); 
        strcat(fullName, ", ");
        strcat(fullName, name); 
        
        cout << "Here's the information in a single string: " << fullName << endl; 
        
        delete fullName; 
        return 0;     
    }
    I thought the code above was correct.

    Code:
    thames@semaht ~/C++/Strings $ valgrind ./personinfo2
    ==3215== Memcheck, a memory error detector
    ==3215== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
    ==3215== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
    ==3215== Command: ./personinfo2
    ==3215== 
    Enter your first name: thames
    Enter your last name: thames
    Here's the information in a single string: thames, thames
    ==3215== Mismatched free() / delete / delete []
    ==3215==    at 0x4C2A44B: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==3215==    by 0x400D1F: main (personinfo2.cpp:27)
    ==3215==  Address 0x5a06040 is 0 bytes inside a block of size 15 alloc'd
    ==3215==    at 0x4C2AAA4: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==3215==    by 0x400C87: main (personinfo2.cpp:19)
    ==3215== 
    ==3215== 
    ==3215== HEAP SUMMARY:
    ==3215==     in use at exit: 0 bytes in 0 blocks
    ==3215==   total heap usage: 1 allocs, 1 frees, 15 bytes allocated
    ==3215== 
    ==3215== All heap blocks were freed -- no leaks are possible
    ==3215== 
    ==3215== For counts of detected and suppressed errors, rerun with: -v
    ==3215== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 2 from 2)
    Last edited by thames; 12-13-2012 at 04:12 PM.

  4. #4
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Why do you not use std::string?
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Maximum File Size
    By dickyDick in forum C++ Programming
    Replies: 3
    Last Post: 08-04-2005, 12:51 AM
  2. Help!Maximum array size in C?
    By robin in forum C Programming
    Replies: 10
    Last Post: 04-02-2005, 11:57 PM
  3. Maximum size of an array in C
    By mehdi_etebari in forum C Programming
    Replies: 8
    Last Post: 02-01-2005, 09:50 AM
  4. Replies: 28
    Last Post: 12-10-2004, 06:49 AM
  5. Maximum array size?
    By code2big in forum C Programming
    Replies: 2
    Last Post: 05-25-2004, 08:16 AM

Tags for this Thread