473,406 Members | 2,404 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,406 software developers and data experts.

programm stops

Hello,

I have a little problem. Perhaps someone can help me. I'm writing a
little menu. So I have to access the menupoints quite often. But the
problem is, that if I'm using file operations (such as fopen) the
program simply stops as if it's waiting for something. I close the
files after use. Some help would be nice, cause I don't know any
further.

Greets
Nov 14 '05 #1
29 1515
Basti <mi***@arcor.de> spoke thus:
I have a little problem. Perhaps someone can help me. I'm writing a
little menu. So I have to access the menupoints quite often. But the
problem is, that if I'm using file operations (such as fopen) the
program simply stops as if it's waiting for something. I close the
files after use. Some help would be nice, cause I don't know any
further.


Post your code, if it's standard C and isn't too lengthy. The first
condition is the really important one:

Your post is off-topic for comp.lang.c. Please visit

http://www.ungerhu.com/jxh/clc.welcome.txt
http://www.eskimo.com/~scs/C-faq/top.html
http://benpfaff.org/writings/clc/off-topic.html

for posting guidelines and frequently asked questions. Thank you.

--
Christopher Benson-Manica | I *should* know what I'm talking about - if I
ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
Nov 14 '05 #2
On 18 Apr 2004 15:33:26 -0700, mi***@arcor.de (Basti) wrote:
Hello,

I have a little problem. Perhaps someone can help me. I'm writing a
little menu. So I have to access the menupoints quite often. But the
problem is, that if I'm using file operations (such as fopen) the
program simply stops as if it's waiting for something. I close the
files after use. Some help would be nice, cause I don't know any
further.

You have an error on line 42. If that doesn't fix the problem, maybe
you could show us the code.
<<Remove the del for email>>
Nov 14 '05 #3
"Basti" <mi***@arcor.de> wrote in message
news:7f**************************@posting.google.c om...
Hello,

I have a little problem. Perhaps someone can help me. I'm writing a
little menu. So I have to access the menupoints quite often. But the
problem is, that if I'm using file operations (such as fopen) the
program simply stops as if it's waiting for something. I close the
files after use. Some help would be nice, cause I don't know any
further.

My guess is that it is indeed waiting (perhaps for a right condition to stop
a loop). Post the code.


Ioannis Vranos

Nov 14 '05 #4
"Ioannis Vranos" <iv*@guesswh.at.emails.ru> wrote in message news:<c5**********@ulysses.noc.ntua.gr>...
"Basti" <mi***@arcor.de> wrote in message
news:7f**************************@posting.google.c om...
Hello,

I have a little problem. Perhaps someone can help me. I'm writing a
little menu. So I have to access the menupoints quite often. But the
problem is, that if I'm using file operations (such as fopen) the
program simply stops as if it's waiting for something. I close the
files after use. Some help would be nice, cause I don't know any
further.

My guess is that it is indeed waiting (perhaps for a right condition to stop
a loop). Post the code.

Okay I understood, that its only possible to answer if you see the
code. So here it is. I think its the error. I mean gdb thinks it is
there. I execute the function seven times to seperate a string into an
array. But if I want to execute it again (still in the programm) seven
times it stops there. I must confess its not really written by me.
Could it be, that there is some malloc problem?
Nov 14 '05 #5
I think I forgot something...

int inputneu(char *inbuffer, char*** outputarray) {

char* buffer;
int argczwei;

buffer = (char*) malloc(strlen(inbuffer) * sizeof(char));
strcpy(buffer, inbuffer);
(*outputarray) = (char**) malloc(100 * sizeof(char**));

argczwei = 0;
(*outputarray)[argczwei++] = strtok(buffer, ";");
while ((((*outputarray)[argczwei] = strtok(NULL, ";")) !=
NULL) ) ++argczwei;
(*outputarray)[argczwei+1] = NULL;
return argczwei;
free(buffer);

}
Nov 14 '05 #6
"Basti" <mi***@arcor.de> wrote in message
news:7f**************************@posting.google.c om...

#include <stdlib.h>
#include <string.h>

int inputneu(char *inbuffer, char*** outputarray) {

char ***? Right (let me see what follows).

char* buffer;
int argczwei;

buffer = (char*) malloc(strlen(inbuffer) * sizeof(char));

strlen() doesn't count '\0' (which always has the value 0 by the way). So
you must allocate one more character/byte.
The casting is not needed and sizeof(char) is always 1 byte. So you can make
it:

buffer = malloc(strlen(inbuffer)+1);
And in general do memory allocations like this:

some_type *p=malloc(some_length*sizeof(*p));
So you could do the above char
*buffer=malloc((strlen(inbuffer)+1)*sizeof(*buffer ));

But since sizeof(*buffer)) is always 1 you can omit it.


if(buffer==NULL)
/* Do something */
strcpy(buffer, inbuffer);

Or better strncpy(buffer, inbuffer, strlen(inbuffer)+1); so as to be
protected from possible buffer overflows.

(*outputarray) = (char**) malloc(100 * sizeof(char**));
outputarray is a temporary pointer variable containing a supposed value you
have passed from the calling function and apparently you are not using. Also
the char *** thing has no use here and the program in general is
non-sense...


argczwei = 0;
(*outputarray)[argczwei++] = strtok(buffer, ";");
while ((((*outputarray)[argczwei] = strtok(NULL, ";")) !=
NULL) ) ++argczwei;
(*outputarray)[argczwei+1] = NULL;
return argczwei;
free(buffer);
Call free() before return.

}



Ioannis Vranos

Nov 14 '05 #7
"Ioannis Vranos" <iv*@guesswh.at.emails.ru> wrote in message
news:c6***********@ulysses.noc.ntua.gr...

So you could do the above char
*buffer=malloc((strlen(inbuffer)+1)*sizeof(*buffer ));

OE cut the line in half, it was

char *buffer= malloc((strlen(inbuffer)+1)*sizeof(*buffer));


Ioannis Vranos

Nov 14 '05 #8

"Basti" <mi***@arcor.de> a écrit dans le message de
news:7f**************************@posting.google.c om...
I think I forgot something...
Hi,
int inputneu(char *inbuffer, char*** outputarray) {
You probably meant char **outputarray. Else, you'll get a useless local copy
of a pointer to a pointer to a pointer to a char instead of working directly
with outputarray.
char* buffer;
int argczwei;

buffer = (char*) malloc(strlen(inbuffer) * sizeof(char));
/* Be careful, inbuffer could be NULL. */
if (inbuffer==NULL) return 0;

/* +1 because strlen returns the lenght of the string without the null
terminating character : usage with strcpy (copies also '\0')*/
buffer = malloc(strlen(inbuffer)+1);

if (buffer)
{
strcpy(buffer, inbuffer);
(*outputarray) = (char**) malloc(100 * sizeof(char**));
if (outputarray)
{

*outputarray = malloc(100*sizeof*outputarray);

argczwei = 0;
(*outputarray)[argczwei++] = strtok(buffer, ";");
while ((((*outputarray)[argczwei] = strtok(NULL, ";")) !=
NULL) ) ++argczwei;
(*outputarray)[argczwei+1] = NULL;
}

Are you sure that argczwei will never exceed 99 ?
free(buffer);
}
else
{
argczwei = 0;
}
return argczwei;

}


Regis
Nov 14 '05 #9


Ioannis Vranos wrote:
#include <stdlib.h>
#include <string.h>

int inputneu(char *inbuffer, char*** outputarray) {
char ***? Right (let me see what follows).

char* buffer;
int argczwei;

buffer = (char*) malloc(strlen(inbuffer) * sizeof(char));


strlen() doesn't count '\0' (which always has the value 0 by the way). So
you must allocate one more character/byte.
The casting is not needed and sizeof(char) is always 1 byte. So you can make
it:

buffer = malloc(strlen(inbuffer)+1);
And in general do memory allocations like this:

some_type *p=malloc(some_length*sizeof(*p));
So you could do the above char
*buffer=malloc((strlen(inbuffer)+1)*sizeof(*buffer ));


Of course you mean
buffer-malloc((

But since sizeof(*buffer)) is always 1 you can omit it.


if(buffer==NULL)
/* Do something */

strcpy(buffer, inbuffer);
Or better strncpy(buffer, inbuffer, strlen(inbuffer)+1); so as to be
protected from possible buffer overflows.


It is impossible to overflow buffer's allocated space. You allocated
strlen(inbuffer)+1. strcpy is safe.
(*outputarray) = (char**) malloc(100 * sizeof(char**));

outputarray is a temporary pointer variable containing a supposed value you
have passed from the calling function and apparently you are not using. Also
the char *** thing has no use here and the program in general is
non-sense...
argczwei = 0;
(*outputarray)[argczwei++] = strtok(buffer, ";");
while ((((*outputarray)[argczwei] = strtok(NULL, ";")) !=
NULL) ) ++argczwei;
(*outputarray)[argczwei+1] = NULL;
return argczwei;

free(buffer);

Call free() before return.

If you call free(buffer) in this function, the calling function cannot
use the array of pointers that was allocated. The pointers would
be pointing to space that has been freed. And, if you don't call
free(buffer) in this function then you have a memory leak. Therefore
the function has a design flaw. You can salvage most of the definition
if you change the protootype to:
char *inputneu(const char *inbuffer, char*** outputarray);
and making the changes in the definition. Still it is a rather
clumsy way to do it.

#include <string.h>
#include <stdio.h>
#include <stdlib.h>

char *inputneu(const char *inbuffer, char*** outputarray)
{
char* buffer;
int argczwei = 0;

if((buffer = malloc(strlen(inbuffer) + 1)) == NULL)
return NULL;
strcpy(buffer, inbuffer);
if((*outputarray = malloc(100 * sizeof(**outputarray)))
== NULL)
{
free(buffer);
return NULL;
}
(*outputarray)[argczwei++] = strtok(buffer, ";");
while (argczwei < 99 && ((*outputarray)[argczwei] =
strtok(NULL, ";")) != NULL ) ++argczwei;
(*outputarray)[argczwei] = NULL;
return buffer;
}

int main(void)
{
char *s ,**tok;
size_t count;

s = inputneu("John;Bill;Harry",&tok);
if(s)
{
for(count = 0;tok[count]; count++)
printf("tok[%u] = %s\n",count,tok[count]);
printf("There are %u strings in tok\n",count);
free(tok);
free(s);
}
return 0;
}

}




Ioannis Vranos


--
Al Bowers
Tampa, Fl USA
mailto: xa******@myrapidsys.com (remove the x to send email)
http://www.geocities.com/abowers822/

Nov 14 '05 #10
Al Bowers <xa******@rapidsys.com> spoke thus:
*buffer=malloc((strlen(inbuffer)+1)*sizeof(*buffer ));
Of course you mean
buffer-malloc((


Of course *you* mean

buffer=malloc((

unless, of course, a function named buffer-malloc is in scope :)

--
Christopher Benson-Manica | I *should* know what I'm talking about - if I
ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
Nov 14 '05 #11
Christopher Benson-Manica <at***@nospam.cyberspace.org> scribbled the following:
Al Bowers <xa******@rapidsys.com> spoke thus:
*buffer=malloc((strlen(inbuffer)+1)*sizeof(*buffer ));
Of course you mean
buffer-malloc((
Of course *you* mean buffer=malloc(( unless, of course, a function named buffer-malloc is in scope :)


buffer-malloc is not a legal identifier.

--
/-- Joona Palaste (pa*****@cc.helsinki.fi) ------------- Finland --------\
\-- http://www.helsinki.fi/~palaste --------------------- rules! --------/
"Products like that make me wish I could menstruate."
- Andy Richter
Nov 14 '05 #12
Ioannis Vranos <iv*@guesswh.at.emails.ru> spoke thus:
Or better strncpy(buffer, inbuffer, strlen(inbuffer)+1); so as to be
protected from possible buffer overflows.


This isn't any safer WRT buffer overflows - the size of buffer is
what's important, not the string length of inbuffer. ITYM

strncpy( buffer, inbuffer, sizeof buffer );

Obviously, buffer must be an array declared in the scope of this
statement for that to work; I haven't read the preceding discussion,
so I don't know whether this is the case.

--
Christopher Benson-Manica | I *should* know what I'm talking about - if I
ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
Nov 14 '05 #13
Joona I Palaste <pa*****@cc.helsinki.fi> spoke thus:
buffer-malloc is not a legal identifier.


Um, right. Whooooops - thanks...

--
Christopher Benson-Manica | I *should* know what I'm talking about - if I
ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
Nov 14 '05 #14
kal
> int inputneu(char *inbuffer, char*** outputarray)
{
char* buffer;
int argczwei;
if (inbuffer == NULL || outputarray == NULL)
return 0;
buffer = (char*) malloc(strlen(inbuffer) * sizeof(char));
strcpy(buffer, inbuffer);
These are not needed. You should operate on the inbuffer itself.
Calling routine has no way of freeing this local 'buffer'. If
you want to keep a copy of the undisturbed inbuffer then make a
copy of it in the calling routine.

(*outputarray) = (char**) malloc(100 * sizeof(char**));
(*outputarray) = (char**) malloc(100 * sizeof(char*));
if (*outputarray == NULL)
return 0;

argczwei = 0;
(*outputarray)[argczwei++] = strtok(buffer, ";");
argczwei = 0;
(*outputarray)[argczwei] = strtok(inbuffer, ";");

while ((((*outputarray)[argczwei] = strtok(NULL, ";")) !=
NULL) ) ++argczwei;
while (argczwei < 99 && (*outputarray)[argczwei] != NULL)
(*outputarray)[++argczwei] = strtok(NULL, ";");

(*outputarray)[argczwei+1] = NULL;
if ((*outputarray)[argczwei] != NULL)
{
if (argczwei < 99)
++argczwei;
(*outputarray)[argczwei] = NULL;
}

return argczwei;
free(buffer);
This free(buffer) is never executed. So, it is not needed.

}

Nov 14 '05 #15
Joona I Palaste <pa*****@cc.helsinki.fi> writes:
Christopher Benson-Manica <at***@nospam.cyberspace.org> scribbled
the following:
Al Bowers <xa******@rapidsys.com> spoke thus:
*buffer=malloc((strlen(inbuffer)+1)*sizeof(*buffer )); Of course you mean
buffer-malloc((

Of course *you* mean

buffer=malloc((

unless, of course, a function named buffer-malloc is in scope :)


buffer-malloc is not a legal identifier.


Right, because "-" is a legal operator (but since malloc() returns a
void*, the result isn't a legal operand (unless you forgot to #include
<stdlib.h> so the compiler thinks malloc() returns int (assuming it's
not a C99 compiler))).

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
Schroedinger does Shakespeare: "To be *and* not to be"
Nov 14 '05 #16
Hi,

thanks a lot for the posts. You helped me a lot. I think I have some
problems with these malloc and free things. Especially in this little
menu thing. When do I free a buffer. For example: I have a function
with some mallocs in it and I know, that I call this function very
often. Do I have to allocate memory and free it again every time I
call the function or do I have to do this only once in a run?

Basti
Nov 14 '05 #17

"Basti" <mi***@arcor.de> a écrit dans le message de
news:7f**************************@posting.google.c om...
Hi,
Hi,

thanks a lot for the posts. You helped me a lot. I think I have some
problems with these malloc and free things. Especially in this little
menu thing. When do I free a buffer. For example: I have a function
with some mallocs in it and I know, that I call this function very
often. Do I have to allocate memory and free it again every time I
call the function or do I have to do this only once in a run?
*The politic to follow is* : each time a call to malloc succeeded (did'nt
returned NULL) to obtain a pointer (elsewhere in the program), you shall
call free to desallocate the memory as soon as you don't need your pointer
anymore (It results that the number of malloc calls should be equal to the
number of free calls in your program). For example, assuming your pointer is
local to a function, yes, you shall allocate and desallocate it in the
function to avoid memory overflow. Be also careful to free only valid
pointers and not null pointers.
BTW, my implementation for inputneu :

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX 100

int inputneu(char * inbuffer, char** outputarray)
{
int argczwei = 0;

if (inbuffer==NULL) return 0;

if (outputarray)
{
*outputarray = malloc(MAX*sizeof*outputarray);

if(*outputarray)
{
outputarray[argczwei] = strtok(inbuffer, ";");
++argczwei;
while ((outputarray[argczwei] = strtok(NULL, ";")) != NULL
&& argczwei++ < MAX);
outputarray[argczwei] = NULL
}
}

return argczwei;
}
int main(void)
{
char **toks;
char buff[]=";toto;tutu;tata; titi;";

toks = malloc(sizeof*toks);

if (toks!=NULL)
{
nbtoks = inputneu(buff, toks);
while(*toks!=NULL)
puts(*toks++);
free(toks);
}

return 0;
}

HTH
Regis

Basti

Nov 14 '05 #18
int main(void)
{
int nbtoks;
char **toks;
char buff[]=";toto;tutu;tata; titi;";

toks = malloc(sizeof*toks);

if (toks!=NULL)
{
nbtoks = inputneu(buff, toks);
while(*toks!=NULL)
puts(*toks++);
free(toks);
}

return 0;
}

Nov 14 '05 #19

"Régis Troadec" <re**@wanadoo.fr> wrote in message
news:c6**********@news-reader2.wanadoo.fr...


*The politic to follow is* : each time a call to malloc succeeded (did'nt
returned NULL) to obtain a pointer (elsewhere in the program), you shall
call free to desallocate the memory as soon as you don't need your pointer
anymore (It results that the number of malloc calls should be equal to the
number of free calls in your program). For example, assuming your pointer is local to a function, yes, you shall allocate and desallocate it in the
function to avoid memory overflow. Be also careful to free only valid
pointers and not null pointers.
BTW, my implementation for inputneu :

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX 100

int inputneu(char * inbuffer, char** outputarray)
{
int argczwei = 0;

if (inbuffer==NULL) return 0;

if (outputarray)
{
*outputarray = malloc(MAX*sizeof*outputarray);

if(*outputarray)
{
outputarray[argczwei] = strtok(inbuffer, ";");
++argczwei;
while ((outputarray[argczwei] = strtok(NULL, ";")) != NULL
&& argczwei++ < MAX);
Doesn't this loop fail with outputarray[100] = strtok should the loop get
that far.
outputarray[argczwei] = NULL
}
}

return argczwei;
}
int main(void)
{
char **toks;
char buff[]=";toto;tutu;tata; titi;";

toks = malloc(sizeof*toks);

if (toks!=NULL)
{
nbtoks = inputneu(buff, toks);
while(*toks!=NULL)
puts(*toks++);
free(toks);
}

return 0;
}


I see the deallocation of toks in main but I don't see the deallocation of
the inputneu function allocation.

Thapani

Nov 14 '05 #20

"Régis Troadec" <re**@wanadoo.fr> wrote in message
news:c6**********@news-reader2.wanadoo.fr...


*The politic to follow is* : each time a call to malloc succeeded (did'nt
returned NULL) to obtain a pointer (elsewhere in the program), you shall
call free to desallocate the memory as soon as you don't need your pointer
anymore (It results that the number of malloc calls should be equal to the
number of free calls in your program). For example, assuming your pointer is local to a function, yes, you shall allocate and desallocate it in the
function to avoid memory overflow. Be also careful to free only valid
pointers and not null pointers.
BTW, my implementation for inputneu :

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX 100

int inputneu(char * inbuffer, char** outputarray)
{
int argczwei = 0;

if (inbuffer==NULL) return 0;

if (outputarray)
{
*outputarray = malloc(MAX*sizeof*outputarray);

if(*outputarray)
{
outputarray[argczwei] = strtok(inbuffer, ";");
++argczwei;
while ((outputarray[argczwei] = strtok(NULL, ";")) != NULL
&& argczwei++ < MAX);
Doesn't this loop fail with outputarray[100] = strtok should the loop get
that far.
outputarray[argczwei] = NULL
}
}

return argczwei;
}
int main(void)
{
char **toks;
char buff[]=";toto;tutu;tata; titi;";

toks = malloc(sizeof*toks);

if (toks!=NULL)
{
nbtoks = inputneu(buff, toks);
while(*toks!=NULL)
puts(*toks++);
free(toks);
}

return 0;
}


I see the deallocation of toks in main but I don't see the deallocation of
the inputneu function allocation.

Thapani


Nov 14 '05 #21

"Thapani Sawaengsri" <th*****@myrapidsys.com> a écrit dans le message de
news:c6************@ID-169908.news.uni-berlin.de...

Hi,
"Régis Troadec" <re**@wanadoo.fr> wrote in message
news:c6**********@news-reader2.wanadoo.fr...

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX 100

int inputneu(char * inbuffer, char** outputarray)
{
int argczwei = 0;

if (inbuffer==NULL) return 0;

if (outputarray)
{
*outputarray = malloc(MAX*sizeof*outputarray);

if(*outputarray)
{
outputarray[argczwei] = strtok(inbuffer, ";");
++argczwei;
while ((outputarray[argczwei] = strtok(NULL, ";")) != NULL
&& argczwei++ < MAX);
Doesn't this loop fail with outputarray[100] = strtok should the loop get
that far.


Damned I am ! Yes, you're right.

while((outputarray[argczwei++] = strtok(NULL, ";")) != NULL && argczwei <
MAX);
outputarray[argczwei] = NULL
}
}

return argczwei;
return argczwei-1;
}
int main(void)
{
char **toks;
char buff[]=";toto;tutu;tata; titi;";

toks = malloc(sizeof*toks);

if (toks!=NULL)
{
nbtoks = inputneu(buff, toks);
while(*toks!=NULL)
puts(*toks++);
free(toks);
}

return 0;
}


I see the deallocation of toks in main but I don't see the deallocation of
the inputneu function allocation.


Ouch again! Furthermore, it's not a good example to apply the things I said
above concerning malloc and free. Thank you for correcting me.
Correction :

int main(void)
{
int nbtoks, i;
char ** toks;
char buff[]=";toto;tutu;tata; titi;";

toks = malloc(sizeof*toks);

if (toks)
{
nbtoks = inputneu(buff, toks);
printf("Nb tokens : %d\n", nbtoks);
for(i=0; i<nbtoks ; ++i)
{
puts(toks[i]);
}

if (*toks)
free(*toks);

free(toks);
}

return 0;
}

}

Regis

Nov 14 '05 #22
kal wrote:
buffer = (char*) malloc(strlen(inbuffer) * sizeof(char));
strcpy(buffer, inbuffer);
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[i] = p;
}

a[i] = NULL;

return a;
}

--
++acr@,ka"
Nov 14 '05 #23
"Régis Troadec" <re**@wanadoo.fr> wrote in message news:<c6**********@news-reader2.wanadoo.fr>...

Be also careful to free only valid
pointers and not null pointers.


Minor nitpick: freeing NULL pointers is just fine, always has
been as far as I know.

From N869, with my >> << added
[#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. <<
Otherwise, if the argument does not match a pointer earlier
returned by the calloc, malloc, or realloc function, or if
the space has been deallocated by a call to free or realloc,
the behavior is undefined.

-David
Nov 14 '05 #24
In <59**************************@posting.google.com > ln********@hotmail.com (David Resnick) writes:
"Régis Troadec" <re**@wanadoo.fr> wrote in message news:<c6**********@news-reader2.wanadoo.fr>...

Be also careful to free only valid
pointers and not null pointers.


Minor nitpick: freeing NULL pointers is just fine, always has
been as far as I know.


Not always, it's a C89 feature. This was a common trap for people using
gcc on SunOS 4. The compiler was C89 conforming and the unsuspecting
programmers assumed full C89 semantics, which was not the case, the
system libraries being pre-ANSI. free(NULL) resulted in a segfault.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #25
Da*****@cern.ch (Dan Pop) writes:
In <59**************************@posting.google.com >
ln********@hotmail.com (David Resnick) writes:
"Régis Troadec" <re**@wanadoo.fr> wrote in message
news:<c6**********@news-reader2.wanadoo.fr>...
Be also careful to free only valid
pointers and not null pointers.


Minor nitpick: freeing NULL pointers is just fine, always has
been as far as I know.


Not always, it's a C89 feature. This was a common trap for people using
gcc on SunOS 4. The compiler was C89 conforming and the unsuspecting
programmers assumed full C89 semantics, which was not the case, the
system libraries being pre-ANSI. free(NULL) resulted in a segfault.


Hmm. I just tried free(NULL) on SunOS 4.1.3 with gcc 2.95.2, and it
worked. But with Sun's pre-C90 compiler, it fails with a segfault.

There are numerous possible explanations for this (and I'm too lazy to
track it down).

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
Schroedinger does Shakespeare: "To be *and* not to be"
Nov 14 '05 #26
In <ln************@nuthaus.mib.org> Keith Thompson <ks***@mib.org> writes:
Da*****@cern.ch (Dan Pop) writes:
In <59**************************@posting.google.com >
ln********@hotmail.com (David Resnick) writes:
>"Régis Troadec" <re**@wanadoo.fr> wrote in message
>news:<c6**********@news-reader2.wanadoo.fr>...
>> Be also careful to free only valid
>> pointers and not null pointers.
>
>Minor nitpick: freeing NULL pointers is just fine, always has
>been as far as I know.


Not always, it's a C89 feature. This was a common trap for people using
gcc on SunOS 4. The compiler was C89 conforming and the unsuspecting
programmers assumed full C89 semantics, which was not the case, the
system libraries being pre-ANSI. free(NULL) resulted in a segfault.


Hmm. I just tried free(NULL) on SunOS 4.1.3 with gcc 2.95.2, and it
worked. But with Sun's pre-C90 compiler, it fails with a segfault.

There are numerous possible explanations for this (and I'm too lazy to
track it down).


Compiling with gcc -v would probably reveal the answer. Could be that
the machine also had the Sun's C89 implementation installed (invoked by
acc or something like that)? Or that later gcc versions took care of the
issue on SunOS 4?

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #27
Da*****@cern.ch (Dan Pop) writes:
In <ln************@nuthaus.mib.org> Keith Thompson <ks***@mib.org> writes:
Da*****@cern.ch (Dan Pop) writes:
In <59**************************@posting.google.com >
ln********@hotmail.com (David Resnick) writes:
>"Régis Troadec" <re**@wanadoo.fr> wrote in message
>news:<c6**********@news-reader2.wanadoo.fr>...
>> Be also careful to free only valid
>> pointers and not null pointers.
>
>Minor nitpick: freeing NULL pointers is just fine, always has
>been as far as I know.

Not always, it's a C89 feature. This was a common trap for people using
gcc on SunOS 4. The compiler was C89 conforming and the unsuspecting
programmers assumed full C89 semantics, which was not the case, the
system libraries being pre-ANSI. free(NULL) resulted in a segfault.


Hmm. I just tried free(NULL) on SunOS 4.1.3 with gcc 2.95.2, and it
worked. But with Sun's pre-C90 compiler, it fails with a segfault.

There are numerous possible explanations for this (and I'm too lazy to
track it down).


Compiling with gcc -v would probably reveal the answer. Could be that
the machine also had the Sun's C89 implementation installed (invoked by
acc or something like that)? Or that later gcc versions took care of the
issue on SunOS 4?


(SunOS 4.1.3 is from around 1989 or so; gcc 2.95.2, which I installed
separately, is from 2001.)

I tried "gcc -v", but the results weren't helpful. The machine
doesn't have Sun's C89 compiler installed. I did see some indications
that it was linking libraries under the gcc installation directory,
but I didn't find a definition of "free" (or "_free") in any of them.

"man free" shows several different versions of the free() function
(declared in <malloc.h>), the default version:

int free(ptr)
char *ptr;

a System V version:

void free(ptr)
void *ptr;

and an XPG2 version:

void free(ptr)
char *ptr;

none of which quite matches either the declaration in
/usr/include/stdlib.h:

extern int free(/* void *ptr */);

or in /usr/include/malloc.h:

typedef char * malloc_t;
extern int free(/* malloc_t ptr */);

(actually, that last one is equivalent to the default version). The
man page doesn't say that any of these can accept a null pointer.

I haven't taken the time to figure out whether these different
versions of free() all exist on the system or how to select which one
I want to use.

It's a big mess, and it makes me very glad this stuff is standardized
now.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
Schroedinger does Shakespeare: "To be *and* not to be"
Nov 14 '05 #28
In <ln************@nuthaus.mib.org> Keith Thompson <ks***@mib.org> writes:
Da*****@cern.ch (Dan Pop) writes:

Compiling with gcc -v would probably reveal the answer. Could be that
the machine also had the Sun's C89 implementation installed (invoked by
acc or something like that)? Or that later gcc versions took care of the
issue on SunOS 4?


(SunOS 4.1.3 is from around 1989 or so; gcc 2.95.2, which I installed
separately, is from 2001.)

I tried "gcc -v", but the results weren't helpful. The machine
doesn't have Sun's C89 compiler installed. I did see some indications
that it was linking libraries under the gcc installation directory,
but I didn't find a definition of "free" (or "_free") in any of them.


Another experiment is to compile a program merely containing a free(NULL)
call and look at the generated assembly code to see if the fix was
not generated inline (it should be obvious even without familiarity with
SPARC assembly). If gcc uses its own version of <stdlib.h>, it might
provide the fix by defining free() as a macro, so you may also want to
try (free)(NULL).

And yet another idea is to do an ldd ./a.out on both the crashing
executable generated by cc and the non-crashing one generated by gcc.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #29
On Mon, 19 Apr 2004 14:58:35 +0000 (UTC), Christopher Benson-Manica
<at***@nospam.cyberspace.org> wrote:
Ioannis Vranos <iv*@guesswh.at.emails.ru> spoke thus:
Or better strncpy(buffer, inbuffer, strlen(inbuffer)+1); so as to be
protected from possible buffer overflows.
This isn't any safer WRT buffer overflows - the size of buffer is
what's important, not the string length of inbuffer. ITYM

Right.
strncpy( buffer, inbuffer, sizeof buffer );

Obviously, buffer must be an array declared in the scope of this
statement for that to work; I haven't read the preceding discussion,
so I don't know whether this is the case.


It's not, it's a pointer to malloc'ed space -- originally
strlen(inbuffer), corrected by Ioannis to strlen(inbuffer)+1, so
sizeof is completely wrong. strncpy for strlen()+1 is correct, but as
you say no safer than strcpy, and more cluttered.

- David.Thompson1 at worldnet.att.net
Nov 14 '05 #30

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
by: Atz | last post by:
Hi to all ! 1.) Is there a way to make exe file from java class file ? 2.) I want to make multiple uninstalation of some files, under windows. E.g. instead of going into control panel ,...
7
by: broebel | last post by:
hey, for the real programmers amongst you, this may be really annoying but I've been learning the language for only two days. this is my problem, in this programm,which already works I now...
1
by: Toni | last post by:
How can I insert a Backgroundimage in my C++ programm? Microsoft Visual Studio C++, Win 32 Konsolenanwendung. Can you answer me in germany, because my english is very bad. An example where very...
0
by: Toni | last post by:
How can I insert a Backgroundimage in my C++ programm? Microsoft Visual Studio C++, Win 32 Konsolenanwendung. Can you answer me in germany, because my english is very bad. An example where very...
0
by: Alexander F?hrmann | last post by:
Grüß euch! Wir haben hier in der Firma ein Problem mit Access! Sobald man im Access den VBA-Editor aufrufen will, kommt folgender fehler! -------------------- Runtime Error!
6
by: TIM | last post by:
for example i have one simple programm int main() { int test = NULL; while(1){ printf("%d\n",test); getch(); test++; }
2
by: Jan | last post by:
Hello! I am looking for a way to do a search&replace in ASCII-Files by a vb.net 2005 programm. Of coarse I can open the files, loop to every line, make a replace, and save the line. But I wonder...
83
by: deppy_3 | last post by:
Hi.I am started learning Programm language C before some time.I am trying to make a programm about a very simple "sell shop".This programm hasn't got any compile problem but when i run it i face...
2
by: LordChaos | last post by:
Dear all, I am a newbie in Java, I got the following problem: I am going through a list of directories. The programm looks inside each directory for specific files and writes them in an...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.