>I was just wondering, is it safe to do something like this?
No, an uninitialized pointer doesn't point to infinite usable memory.
>Basically, what if it is impossible to calculate the amount
>of space required to hold everything in the array?
Then you've done something wrong. You should always be able to calculate the size of your memory blocks to within a reasonable margin of waste, or you should be able to incrementally resize your blocks until all of the data is stored.
In your specific case, it's possible to calculate the necessary size for msg by taking the length of fname and adding it to the length of the format string. Alternatively you could use something like snprintf, which is generally better at giving you more information.
For things like streamed input where you simply cannot calculate the final length ahead of time, you're stuck with using a fixed-size block to read chunks and growing the result buffer until there aren't any more chunks.
Narue
Bad Cop
15,460 posts since Sep 2004
Reputation Points: 6,464
Solved Threads: 1,401
int totalLen = strlen(formatstr) + strlen(name);
I would try to avoid this kind of statements since the order of evaluation of the two functions is not defined. If one function affects the result of the other, then side effects will result.
char* buffer = (char*) malloc (sizeof(char) * totalLen); // allocate memory
Casting the return of malloc is not a good practice neither.sizeof(char) is redundant since char is a byte. It would be better to sizeof(*buffer) in that way if the pointer type gets changed still works. Forgot to add +1 in malloc, for the '\0'.
free(buffer);
freeing memory that it might not be allocated is a no no. Check that malloc was succesful.
Aia
Nearly a Posting Maven
2,392 posts since Dec 2006
Reputation Points: 2,224
Solved Threads: 218
> >> len = sprintf(NULL,"This is my forename: %s",fname);
> seems to work perfectly!!!
> Is there an assurance that the string will not be written if NULL is passed?
> I believe not. Is this undefined behavior?
It certainly is undefined behaviour.
However, if you have a C99 compiler, then you have snprintf() as well. It is legal to pass NULL to this in order to measure the length of a formatted string.
Salem
Posting Sage
11,531 posts since Dec 2005
Reputation Points: 5,862
Solved Threads: 953
As far as I know it's scprintf(const char*,...) in C99 counts the length of a formatted string (and it's not legal to pass null pointer to sprintf family functions).
May be, I'm wrong?..
ArkM
Postaholic
2,001 posts since Jul 2008
Reputation Points: 1,234
Solved Threads: 348
There is no scprintf in ANSI.
It's a Microsoft thing to solve the same problem.
Salem
Posting Sage
11,531 posts since Dec 2005
Reputation Points: 5,862
Solved Threads: 953
Testing buffer before free achieves nothing useful.
Description
2 The free function causes the space pointed to by ptr to be deallocated, that is, made
available for further allocation. If ptr is a null pointer, no action occurs.
If buffer is NULL, then freeing it does nothing
If buffer is not NULL, but a garbage pointer, then the test doesn't save you from disaster.
But setting buffer to NULL afterwards is definitely a good idea, as it will easily detect any inadvertant "use after free" mistakes.
Salem
Posting Sage
11,531 posts since Dec 2005
Reputation Points: 5,862
Solved Threads: 953
2Aia:
Please explain how to rewrite this code without casting of the return value of malloc. I think it simply wouldn't compile without explicit typecast to (char*).
Include the header file stdlib.h where malloc is prototype correctly. Some more on it .
Aia
Nearly a Posting Maven
2,392 posts since Dec 2006
Reputation Points: 2,224
Solved Threads: 218
> I think it simply wouldn't compile without explicit typecast to (char*).
Only in two cases, neither of them good.
1) you're using a pre-ansi compiler, where malloc returns the previous 'any' pointer type of char*. Since ANSI first came out in 1989 (that's 20 years ago!), why are you still using such a fossil?
2) you're using a C++ compiler to compile C code. In which case, learn to use the correct tool for the job. Don't mung your programs into polyglots just to make them compile as C or C++. All that leads to is code which is both bad C and bad C++.
You don't need to cast malloc in a valid ANSI C program, compiled with an ANSI C compiler.
Salem
Posting Sage
11,531 posts since Dec 2005
Reputation Points: 5,862
Solved Threads: 953