kal said:
These are not needed. You should operate on the inbuffer itself.
Although the original code does not inspire much confidence in its
creator, I do suspect that he would've done this if it was okay to
modify the input string. (strtok is called on it.)
Calling routine has no way of freeing this local 'buffer'.
It does if the first character is not the separator (or the string
is empty); **outputarray will be equal to buffer.
argczwei = 0;
(*outputarray)[argczwei++] = strtok(buffer, ";");
argczwei = 0;
(*outputarray)[argczwei] = strtok(inbuffer, ";");
No, the original can be assumed to be correct in both of these two
aspects, in the absence of a precise specification.
(*outputarray)[argczwei+1] = NULL;
In the original, this line is completely unnecessary.
Is everyone responding to this thread drunk or somesuch? Unusually
for this group, not one wholly correct answer has yet been posted;
at least, none have arrived here.
Obviously, the malloc(strlen(buf)) thing is probably what's making
trouble for the OP, but this function is, quite simply, by far too
ugly to live. Write a well-specified replacement; in fact, here's
my attempt, although I may've mistaken the intent. (It's probably
best not to try to actually use it; I haven't properly checked its
functionality or Standard-conformance status.)
#include <stdlib.h>
#include <string.h>
#include <limits.h>
/*
* Construct a null-terminated array of tokens from a given string
* of the form "token1:token2:...\0" where each tokenN is a string
* of characters not in the separator string and ':' is matched by
* any character in the separator string; return a pointer to this
* array, whose memory can be deallocated with free(), as can that
* of the tokens themselves as a unit by passing the first element
* only. Tokens may be empty.
*
* If the input string or the separator is a null pointer, returns
* a null-pointer. This also occurs if memory allocation fails at
* any point, probably due to exceeding either a system-wide limit
* or a process quota.
*
* FIXME: will fail spectaculary if char is a large type.
*/
/* Must be at least 2. */
#define INITIAL_SIZE 16
char **
tokens( const char *input, const char *separators )
{
/* char here is arbitrary; only 0 and 1 are stored */
char sep[CHAR_MAX - CHAR_MIN + 1] = { 1 };
char **a, *p;
size_t i, size = INITIAL_SIZE;
if (!input || !separators)
return NULL;
a = malloc( size * sizeof *a );
if (!a)
return NULL;
*a = malloc( strlen( input ) + 1);
if (!*a) {
free( a );
return NULL;
}
memcpy( *a, input, strlen( input ) + 1 );
if (!*separators) {
a[1] = NULL;
return a;
}
do
sep[*separators++] = 1;
while (*separators);
/*
* Pointless exercise: how can this be changed so that the
* condition is the only way that the loop is ever broken?
* I realised that I should give in when I found the comma
* operator in the condition, which is certainly much more
* evil than almost any use of the break statement.
*
* Of course, there should be no extra variables and not a
* hint of overloading existing ones.
*/
for (i = 1, p = *a; *p; i++) {
if (i + 1 >= size) {
char **new;
size *= 2;
new = realloc( a, size * sizeof *a );
if (!new) {
free( *a );
free( a );
return NULL;
}
a = new;
}
while (!sep[*p])
p++;
if (!*p)
break;
*p++ = 0;
a
= p;
}
a = NULL;
return a;
}