programm stops

B

Basti

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
 
C

Christopher Benson-Manica

Basti said:
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.
 
B

Barry Schwarz

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>>
 
I

Ioannis Vranos

Basti said:
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
 
B

Basti

Ioannis Vranos said:
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?
 
B

Basti

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);

}
 
I

Ioannis Vranos

#include <stdlib.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
 
I

Ioannis Vranos

Ioannis Vranos said:
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
 
R

Régis Troadec

Basti said:
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
 
A

Al Bowers

Ioannis said:
#include <stdlib.h>




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







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 */







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;
}
 
C

Christopher Benson-Manica

Ioannis Vranos said:
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.
 
K

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.
 
K

Keith Thompson

Joona I Palaste said:
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))).
 
B

Basti

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
 
R

Régis Troadec

Basti said:
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
 
T

Thapani Sawaengsri

Régis Troadec said:
*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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,141
Messages
2,570,817
Members
47,367
Latest member
mahdiharooniir

Latest Threads

Top