LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 03-14-2005, 12:13 AM   #1
The_Nerd
Member
 
Registered: Aug 2002
Distribution: Debian
Posts: 540

Rep: Reputation: 32
vsnprintf is broken


Alright, here is my code:

Code:
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <stdarg.h>

void Message(char *cpStr, ...)
{
	va_list args;
	va_start(args, cpStr);
	long lLength;
	char *cpTemp;
	lLength=vsnprintf(NULL, 0, cpStr, args);
	cpTemp=(char *)malloc((lLength+1)*sizeof(char));
	if (!cpTemp)
	{
		fprintf(stderr, "Error: Unable to allocate memory for opperation");
	}
	if (vsnprintf(cpTemp, lLength, cpStr, args)<0)
	{
		fprintf(stderr, "Error: Unable to complete opperation");
	}
	va_end(args);
	fprintf(stderr, "%s\n", cpTemp);
	free(cpTemp);
}

int main(int argc, char **argv)
{
	Message("Initializing SDL. %s\n", "Hello world!");
}
I compile this with g++, and the programs runs. However, the string it prints is:

Code:
Initializing SDL. g
When it should be:

Code:
Initializing SDL. Hello World!
I've already tested lLength, it is holding the correct length after the call to the first vsnprintf(NULL, 0, etc, etc...);

Help would be good!

My system is a 64bit system running Fedora Core 3.
 
Old 03-14-2005, 05:17 AM   #2
Hivemind
Member
 
Registered: Sep 2004
Posts: 273

Rep: Reputation: 30
The following code works for me. Note that I am not including malloc.h. It's a non-standard header that's not needed in your program. vsnprintf() is also non-standard btw.

Code:
#include <assert.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>

static void message(const char *, ...);

int
main(void)
{
   message("Hello, %s\n", "World!");

   return 0;
}

static void
message(const char *format, ...)
{
   va_list args;
   int length = 0;
   char *buffer = NULL;

   va_start(args, format);

   length = vsnprintf(NULL, 0, format, args);

   assert(length > 0);

   ++length; /* Make sure we have room for \0 */

   buffer = malloc(length); /* sizeof(char) not needed */

   vsnprintf(buffer, length, format, args);

   va_end(args);

   printf("%s", buffer);

   free(buffer);
}

Last edited by Hivemind; 03-14-2005 at 05:53 AM.
 
Old 03-14-2005, 05:56 AM   #3
Hivemind
Member
 
Registered: Sep 2004
Posts: 273

Rep: Reputation: 30
One more thing: If the string passed to the message() function doesn't end with a newline you might want to flush the output buffer so you make sure the string is displayed right away.
 
Old 03-14-2005, 05:00 PM   #4
itsme86
Senior Member
 
Registered: Jan 2004
Location: Oregon, USA
Distribution: Slackware
Posts: 1,246

Rep: Reputation: 59
Tell me where you found that it was okay to pass a NULL pointer as the first argument to vsnprintf() like you did here:
Code:
lLength=vsnprintf(NULL, 0, cpStr, args);
This is most likely evil. And trust me, the last place you want to declare as the broken part of your code is within a libc function. Guaranteed you're just using it incorrectly.
 
Old 03-14-2005, 05:11 PM   #5
Hivemind
Member
 
Registered: Sep 2004
Posts: 273

Rep: Reputation: 30
Works fine with newlib's vsnprintf() too.
My manual says:
The number of characters that would have been written into the array, not counting the terminating null character, had count been large enough. It does this even if count is zero; in this case buf can be NULL.
 
Old 03-14-2005, 07:00 PM   #6
keefaz
LQ Guru
 
Registered: Mar 2004
Distribution: Slackware
Posts: 6,552

Rep: Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872
There is a working sample code for vsnprintf() in the corresponding man page, just use it
 
Old 03-14-2005, 07:33 PM   #7
itsme86
Senior Member
 
Registered: Jan 2004
Location: Oregon, USA
Distribution: Slackware
Posts: 1,246

Rep: Reputation: 59
Quote:
Works fine with newlib's vsnprintf() too.
My manual says:
The number of characters that would have been written into the array, not counting the terminating null character, had count been large enough. It does this even if count is zero; in this case buf can be NULL.
I stand corrected. Apologies.
 
Old 03-17-2005, 12:21 PM   #8
The_Nerd
Member
 
Registered: Aug 2002
Distribution: Debian
Posts: 540

Original Poster
Rep: Reputation: 32
I tried man pages, webpages, and it was still broken. Not to mention that it works on another computer! Anyhow, I just wrote my own, and it works fine. Thanks guys.
 
Old 02-10-2006, 03:46 PM   #9
akulo
LQ Newbie
 
Registered: Feb 2006
Posts: 1

Rep: Reputation: 0
vsnprintf() on a 64--bit machine running Linux

Like the original poster, I've been having problems with vsnprintf() producing garbage on a 64--bit machine running Linux (SuSE, not Fedora). I've found a workaround, at least on my system:

Code:
	va_list args;

	va_start(args, cpStr);

	long lLength;
	char *cpTemp;
	lLength=vsnprintf(NULL, 0, cpStr, args);
	cpTemp=(char *)malloc((lLength+1)*sizeof(char));
	if (!cpTemp)
	{
		fprintf(stderr, "Error: Unable to allocate memory for opperation");
	}

	va_end(args);

	va_start(args, cpStr);

	if (vsnprintf(cpTemp, lLength, cpStr, args)<0)
	{
		fprintf(stderr, "Error: Unable to complete opperation");
	}

	va_end(args);

	fprintf(stderr, "%s\n", cpTemp);
	free(cpTemp);
.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
broken grub gravesb Linux - Software 5 06-13-2005 11:19 PM
Broken partitions a_user Fedora 2 06-09-2005 01:57 PM
su is broken Smokey Slackware 1 01-29-2005 02:31 PM
what's with all those broken packages darkleaf Debian 8 09-29-2004 01:40 PM
X is broken jclark00001 Linux - Software 6 04-27-2003 07:56 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 02:26 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration