Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » sprintf() and size restrictions

Credits go to Kitty Cat for helping out!
This thread is locked; no one can reply to it. rss feed Print
sprintf() and size restrictions
OnlineCop
Member #7,919
October 2006
avatar

I have a small char array (let's say 10 bytes) that I want to pass into sprintf(). What happens if sprintf() pushes too much onto that array? Here's an example of how to reproduce this:

1#include <iostream>
2 
3int main()
4{
5 int a = 1234;
6 char buffer[10] = {0};
7 
8 // This should be "10"
9 std::cerr << "The size of buffer is: " << sizeof(buffer);
10 
11 // This should be "0"
12 std::cerr << ", and the string length of buffer: " << strlen(buffer);
13 std::cerr << std::endl;
14 
15 // stuff buffer[] with more than 10 chars
16 sprintf(buffer, "I will stuff 'buffer' with lots of text and numbers (like %d)!\n", a);
17 
18 // This should still be "10"
19 std::cerr << "Now the size of buffer is: " << sizeof(buffer);
20 
21 // This results in "65"
22 std::cerr << ", and the string length of buffer is: " << strlen(buffer);
23 std::cerr << std::endl;
24 
25 return 0;
26}

This will crash with a SEGFAULT (so if you run it, do it through a debugger). Apparently, sprintf() is unsafe and "keeps going until it's done" but doesn't do any bounds checking.

Is there a "safe" sprintf() function, like sprintnf() that I can use to ensure that I don't exceed a specified size?

Kitty Cat
Member #2,815
October 2002
avatar

Quote:

Apparently, sprintf() is unsafe and "keeps going until it's done" but doesn't do any bounds checking.

Of course, because you don't tell it how big its bounds are (it's not psychic).

Quote:

Is there a "safe" sprintf() function, like sprintnf() that I can use to ensure that I don't exceed a specified size?

snprintf
Or using that other OS that doesn't like to play by everyone else's standards: _snprintf or sprintf_s.

--
"Do not meddle in the affairs of cats, for they are subtle and will pee on your computer." -- Bruce Graham

OnlineCop
Member #7,919
October 2006
avatar

Perfect. Thanks, KC!

Thomas Fjellstrom
Member #476
June 2000
avatar

I personally like using the return value of snprintf, and passing NULL to the string arg so it just calculates the total length, and then allocating a properly sized buffer to do it again.

Another option is to use GCC's asprintf. It allocates the buffer for you.

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

Goalie Ca
Member #2,579
July 2002
avatar

Uhh... you're using iostream and sprintf? Why???

Use #include <strstream>

-------------
Bah weep granah weep nini bong!

bamccaig
Member #7,536
July 2006
avatar

Thomas Fjellstrom said:

I personally like using the return value of snprintf, and passing NULL to the string arg so it just calculates the total length, and then allocating a properly sized buffer to do it again.

O_o

    char* buf = NULL;
    int len = 0;

    len = snprintf(buf, 0, "foo");
    buf = (char*)malloc(len+1);
    len = snprintf(buf, len, "foo");

???

Thomas Fjellstrom
Member #476
June 2000
avatar

    char* buf = NULL;
    int len = 0;

    len = snprintf(buf, 0, "foo");
    buf = (char*)malloc(len);
    len = snprintf(buf, len, "foo");

pretty much, though I'd do it like so:

    char* buf = NULL;
    int len = 0;

    len = snprintf(NULL, 0, "foo");
    buf = (char*)malloc(len+1);
    snprintf(buf, len, "foo");

Just to be obvious about the NULL bit.

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

BAF
Member #2,981
December 2002
avatar

Stringstream = better.

OnlineCop
Member #7,919
October 2006
avatar

Is there a sprintf()-style function available for std::string? If so, you wouldn't need to worry about memory allocation/deallocation or string length.

Does std::stringstream allow you to do this?

LennyLen
Member #5,313
December 2004
avatar

Quote:

Stringstream = better.

Though you get problems trying to use it in C. ;)

BAF
Member #2,981
December 2002
avatar

OnlineCop: yes.

Go to: