Memory corruption on freeing a pointer to pointer

G

gdotone

/* This program creates and uses pointers to pointer of type char,
pointer to arrays of char, malloc(), to allocate memory for
the pointer to pointer and 1-D arrays, strlen(), sizeof(),
and strtok(). Using those functions the program separates words,
in array of character arrays, and string constants. It places
those words in an allocated spaces. This program builds from
simple statements and ideas so not to overwhelm. */

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

int main( void )
{
char **a;
int numberOfPointers = 5;

a = (char **) malloc ( numberOfPointers * ( sizeof(char * ) ) );

if ( a!= NULL )
printf( "the array, a, points to declare space\n\n" );

char *b[] = { "one", "two", "three", "four", "five" };

a = b;

for ( int index = 0; index < 5; index++ )
{
printf( "%s\n\n", *(a+index) );
}

for ( int index = 0; index < 5; index++ )
{
printf( "%s\n\n", *(a+index) );
}

char *string = "word" ;

size_t n = strlen( string );

printf("\n %zd \n\n", n); /* %zd because n is of type size_t */

char sentence[] = "this is a sentence with words";
char *token = " ";
char *g;

g = strtok(sentence, token);

size_t y = strlen(g);

printf("the length of the first word in the sentence is %d\n\n", (int) y );

char *c_space = (char *) malloc( y * sizeof(char) + 1 );

if (c_space)
{
printf("got space for word\n\n");
}

int indexnewstring = (int) y + 1; /* (int) strlen( g ) + 1 */

char newstring[indexnewstring];

char *v = strcpy( newstring, g);
printf(" %s\n", v );

char sentence2[] = "this is a sentence with words";
g = strtok( sentence2, token );

while ( g != NULL )
{
printf("\n %s", g );
g = strtok( NULL, token );
}

printf("\n");

char sentence3[] = "C programming actually is the fun";

for( g = strtok(sentence3, token ); g != NULL; g = strtok( NULL, token ) )
printf (" %s\n", g );

return 0;
}

Questions: How do you free a pointer to a pointer of what it points to?
How would you free the pointer of the pointer a. (a+index)?
strtok(), on my machine, seems to only take an array of characters. Is
the function suppose to string constants too.
sen4 = {"this is a short sentence"};

ken i hope this posting is better. let me know. thanks.
 
G

gdotone

/* This program creates and uses pointers to pointer of type char,

pointer to arrays of char, malloc(), to allocate memory for

the pointer to pointer and 1-D arrays, strlen(), sizeof(),

and strtok(). Using those functions the program separates words,

in array of character arrays, and string constants. It places

those words in an allocated spaces. This program builds from

simple statements and ideas so not to overwhelm. */



#include <stdio.h>

#include <stdlib.h>

#include <string.h>



int main( void )

{

char **a;

int numberOfPointers = 5;



a = (char **) malloc ( numberOfPointers * ( sizeof(char * ) ) );



if ( a!= NULL )

printf( "the array, a, points to declare space\n\n" );



char *b[] = { "one", "two", "three", "four", "five" };



a = b;



for ( int index = 0; index < 5; index++ )

{

printf( "%s\n\n", *(a+index) );

}



for ( int index = 0; index < 5; index++ )

{

printf( "%s\n\n", *(a+index) );

}



char *string = "word" ;



size_t n = strlen( string );



printf("\n %zd \n\n", n); /* %zd because n is of type size_t */



char sentence[] = "this is a sentence with words";

char *token = " ";

char *g;



g = strtok(sentence, token);



size_t y = strlen(g);



printf("the length of the first word in the sentence is %d\n\n", (int) y );



char *c_space = (char *) malloc( y * sizeof(char) + 1 );



if (c_space)

{

printf("got space for word\n\n");

}



int indexnewstring = (int) y + 1; /* (int) strlen( g ) + 1 */



char newstring[indexnewstring];



char *v = strcpy( newstring, g);

printf(" %s\n", v );



char sentence2[] = "this is a sentence with words";

g = strtok( sentence2, token );



while ( g != NULL )

{

printf("\n %s", g );

g = strtok( NULL, token );

}



printf("\n");



char sentence3[] = "C programming actually is the fun";



for( g = strtok(sentence3, token ); g != NULL; g = strtok( NULL, token ) )

printf (" %s\n", g );



return 0;

}



Questions: How do you free a pointer to a pointer of what it points to?

How would you free the pointer of the pointer a. (a+index)?

strtok(), on my machine, seems to only take an array of characters. Is

the function suppose to string constants too.

sen4 = {"this is a short sentence"};



keith i hope this posting is better. let me know. thanks.

to free the memory of what a's pointers point to would it be:
free((void *) a+index);

thanks.
 
I

Ike Naar

James Kuyper said:
On 08/24/2013 03:05 PM, Sharwan Joram wrote: [...]
if ( NULL == parameters[parametercount]){

This is what's known as a "Yoda conndition"
<http://en.wikipedia.org/wiki/Yoda_Conditions>. I know that a lot of
programmers like them, and for somewhat valid reasons, but personally I
find them jarring and unnecessary. Personally, I'd write that as:

if (parameters[parametercount] == NULL) {

Does it matter? The == operator is symmetric, (X==Y) == (Y==X).

If (X==Y) is jarring and unnecessary, then, for symmetry reasons
(Y==X) is unnecessary and jarring.

"It is allowed on all hands, that the primitive way of breaking
eggs, before we eat them, was upon the larger end; but his present
majesty's grandfather, while he was a boy, going to eat an egg,
and breaking it according to the ancient practice, happened to cut
one of his fingers. Whereupon the emperor his father published an
edict, commanding all his subjects, upon great penalties, to break
the smaller end of their eggs. The people so highly resented this
law, that our histories tell us, there have been six rebellions
raised on that account; wherein one emperor lost his life, and
another his crown. These civil commotions were constantly fomented
by the monarchs of Blefuscu; and when they were quelled, the exiles
always fled for refuge to that empire. It is computed that eleven
thousand persons have at several times suffered death, rather than
submit to break their eggs at the smaller end"
(Jonathan Swift, Gulliver's Travels, part 1: A Voyage to Lilliput)
 
G

gdotone

/* this runs to end, does it do what you what?, stick some data in and see */
/* tried to stick with your main thoughts, variable, etc */

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


int main(int argc, const char * argv[])
{

char **parameters;
int idx = 0;
int parameterCount = 5; /* initializing for the purposes of testing */

// char *saved_token; /* would suggest renaming this variable */
/* *saved_token must point to a string */
/* constant from somewhere. using a string */
/* const creates a memory error for my compiler */
/* Clang. but strtok() works fine with an */
/* char array */

char saved_token[] = "I was initialized by another function";

char *token; /* change from a char to char * */


parameters = (char **)malloc(parameterCount * sizeof(char *));
/* you should add your check using fprintf ... */


/* hopefully placing parameterCount in for header is not that big a */
/* for you */

parameterCount = 0;

/* i don't understand token && *token */
/* when are you trying to end the loop, at the end of the saved_token? */

for( token = strtok(saved_token, " "); token =='\0' ; token = strtok(NULL, " "))
{
parameters[parameterCount] = (char *)malloc(30 * sizeof (char *));
/* you should add your check using fprintf ... */

/* many have said just use strcpy(). well yeah it would copy the */
/* tokens in the space allocated */
/* calloc is nice too, but orignal code was not bad, in the sense */
/* of being poorly thought out. it was a good shot. */
/* the question is this the way you need to do it or just want to */
/* to do it */

memset(parameters[parameterCount], '\0', 30);
memcpy(parameters[parameterCount], token, strlen(token));
parameters[parameterCount] = token;

/* adding idx to your for loop so it can keep count of your tokens */
idx++; /* idx will count the number of tokens */

}

/* idx contains the number of tokens */
if (parameters != NULL)
{
for ( idx = 0; idx <= parameterCount; idx++ ) /* changed from orig */
{
free((void *)parameters+idx);
} /* braces added to draw attention only, not need of course */

free((void *) *parameters); /* not sure this frees what you want */

}

return 0;
}
 
G

gdotone

/* this runs to end, does it do what you what?, stick some data in and see */

/* tried to stick with your main thoughts, variable, etc */



#include <stdio.h>

#include <stdlib.h>

#include <string.h>





int main(int argc, const char * argv[])

{



char **parameters;

int idx = 0;

int parameterCount = 5; /* initializing for the purposes of testing */



// char *saved_token; /* would suggest renaming this variable */

/* *saved_token must point to a string */

/* constant from somewhere. using a string */

/* const creates a memory error for my compiler */

/* Clang. but strtok() works fine with an */

/* char array */



char saved_token[] = "I was initialized by another function";



char *token; /* change from a char to char * */





parameters = (char **)malloc(parameterCount * sizeof(char *));

/* you should add your check using fprintf ... */





/* hopefully placing parameterCount in for header is not that big a */

/* for you */



parameterCount = 0;



/* i don't understand token && *token */

/* when are you trying to end the loop, at the end of the saved_token? */



for( token = strtok(saved_token, " "); token =='\0' ; token = strtok(NULL, " "))

{

parameters[parameterCount] = (char *)malloc(30 * sizeof (char *));

/* you should add your check using fprintf ... */



/* many have said just use strcpy(). well yeah it would copy the */

/* tokens in the space allocated */

/* calloc is nice too, but orignal code was not bad, in the sense */

/* of being poorly thought out. it was a good shot. */

/* the question is this the way you need to do it or just want to */

/* to do it */



memset(parameters[parameterCount], '\0', 30);

memcpy(parameters[parameterCount], token, strlen(token));

parameters[parameterCount] = token;



/* adding idx to your for loop so it can keep count of your tokens */

idx++; /* idx will count the number of tokens */



}



/* idx contains the number of tokens */

if (parameters != NULL)

{

for ( idx = 0; idx <= parameterCount; idx++ ) /* changed from orig */

{

free((void *)parameters+idx);

} /* braces added to draw attention only, not need of course */



free((void *) *parameters); /* not sure this frees what you want */



}



return 0;

}
i made a logical i see in the for loop... token != '\0'
i don't think even changing it to this is logically correct...
 
J

James Kuyper

James Kuyper said:
On 08/24/2013 03:05 PM, Sharwan Joram wrote: [...]
if ( NULL == parameters[parametercount]){

This is what's known as a "Yoda conndition"
<http://en.wikipedia.org/wiki/Yoda_Conditions>. I know that a lot of
programmers like them, and for somewhat valid reasons, but personally I
find them jarring and unnecessary. Personally, I'd write that as:

if (parameters[parametercount] == NULL) {

Does it matter? The == operator is symmetric, (X==Y) == (Y==X).

If (X==Y) is jarring and unnecessary, then, for symmetry reasons
(Y==X) is unnecessary and jarring.

If jarring and unnecessary is (X==Y), then for symmetry reasons,
unnecessary and jarring is (Y==X).
 
J

James Kuyper

/* This program creates and uses pointers to pointer of type char,
pointer to arrays of char, malloc(), to allocate memory for
the pointer to pointer and 1-D arrays, strlen(), sizeof(),
and strtok(). Using those functions the program separates words,
in array of character arrays, and string constants. It places
those words in an allocated spaces. This program builds from
simple statements and ideas so not to overwhelm. */

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

int main( void )
{
char **a;
int numberOfPointers = 5;

a = (char **) malloc ( numberOfPointers * ( sizeof(char * ) ) );

The cast is unnecessary, and if you compile using C90, could mask an error.
if ( a!= NULL )
printf( "the array, a, points to declare space\n\n" );

char *b[] = { "one", "two", "three", "four", "five" };

a = b;

for ( int index = 0; index < 5; index++ )
{
printf( "%s\n\n", *(a+index) );

*(a+index) is exactly equivalent to a[index]. It only saves two
characters in typing, but it also makes it easier to read.
}

for ( int index = 0; index < 5; index++ )
{
printf( "%s\n\n", *(a+index) );
}

char *string = "word" ;

size_t n = strlen( string );

printf("\n %zd \n\n", n); /* %zd because n is of type size_t */

char sentence[] = "this is a sentence with words";
char *token = " ";
char *g;

g = strtok(sentence, token);

The second argument of strtok is a list of delimiters that are be used
for breaking the string up into tokens. Naming that list "token"
suggests a misunderstanding of some kind (except for entries in the
Obfuscated C contest).
size_t y = strlen(g);

printf("the length of the first word in the sentence is %d\n\n", (int) y );

char *c_space = (char *) malloc( y * sizeof(char) + 1 );

The cast is unnecessary in C. sizeof(char) is inherently 1, so that
should be just y+1.
if (c_space)
{
printf("got space for word\n\n");
}

You reserve space for the word, but then don't use it, and also don't
free() it, so you've got a memory leak. I presume this is related to
your question below, even though it involves neither 'a' nor 'index'.
int indexnewstring = (int) y + 1; /* (int) strlen( g ) + 1 */

The cast is unnecessary. You should only use casts when they are
necessary. Any time you read or write a cast in a piece of C code, you
should examine it carefully, because necessary casts can do dangerous
things, things that often shouldn't be done. When you insert unnecessary
casts in your code, you make it harder to treat the necessary casts with
the proper level of caution.
char newstring[indexnewstring];

char *v = strcpy( newstring, g);
printf(" %s\n", v );

char sentence2[] = "this is a sentence with words";
g = strtok( sentence2, token );

while ( g != NULL )
{
printf("\n %s", g );
g = strtok( NULL, token );
}

printf("\n");

char sentence3[] = "C programming actually is the fun";

for( g = strtok(sentence3, token ); g != NULL; g = strtok( NULL, token ) )
printf (" %s\n", g );

return 0;
}

Questions: How do you free a pointer to a pointer of what it points to?
How would you free the pointer of the pointer a. (a+index)?

I'm not sure I understand your question, because the answer seems to be
too simple to cause any confusion, and refers to a case that comes up
nowhere in the above code. The rule of thumb is that if you have

expression = malloc(count * sizeof *expression)

Then it should be matched by:

free(expression);

Such matching pieces of code are sometime referred to metaphorically as
"bookend code". In the above code, you should somewhere have had

a[index] = malloc(count * sizeof *a[index]);

in which case the matching free should look like

free(a[index]);

Note that you should NOT free(a) until you've already called
free(a[index]) for every case where a[index] contains a pointer returned
by a call to malloc(). No such cases come up in your code above.

Does that answer your question? If not, could you explain the context of
the question more explicitly, preferably in the form of C code?
strtok(), on my machine, seems to only take an array of characters. Is
the function suppose to string constants too.
sen4 = {"this is a short sentence"};

No. strtok() writes to the array that it is parsing. Writing to the
array pointed at by a string literal has undefined behavior, so you
should definitely NOT write such code.
 
J

James Kuyper

James Kuyper said:
On 08/24/2013 03:05 PM, Sharwan Joram wrote: [...]
if ( NULL == parameters[parametercount]){

This is what's known as a "Yoda conndition"
<http://en.wikipedia.org/wiki/Yoda_Conditions>. I know that a lot of
programmers like them, and for somewhat valid reasons, but personally I
find them jarring and unnecessary. Personally, I'd write that as:

if (parameters[parametercount] == NULL) {

Does it matter? The == operator is symmetric, (X==Y) == (Y==X).

Yes, it matters - because it's intended to protect against the typo
which replaces == with =, by ensuring that it would cause a constraint
violation. The assignment operator is very definitely not symmetric.
 
B

Barry Schwarz

/* This program creates and uses pointers to pointer of type char,
pointer to arrays of char, malloc(), to allocate memory for
the pointer to pointer and 1-D arrays, strlen(), sizeof(),
and strtok(). Using those functions the program separates words,
in array of character arrays, and string constants. It places
those words in an allocated spaces. This program builds from
simple statements and ideas so not to overwhelm. */

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

int main( void )
{
char **a;
int numberOfPointers = 5;

a = (char **) malloc ( numberOfPointers * ( sizeof(char * ) ) );

if ( a!= NULL )
printf( "the array, a, points to declare space\n\n" );

a is not an array. It points to allocated memory.
char *b[] = { "one", "two", "three", "four", "five" };

a = b;

The allocated memory that a used to point to is now completely
inaccessible. It cannot be used nor can it be freed. This is a
classic memory leak.
for ( int index = 0; index < 5; index++ )
{
printf( "%s\n\n", *(a+index) );
}

for ( int index = 0; index < 5; index++ )
{
printf( "%s\n\n", *(a+index) );
}

char *string = "word" ;

size_t n = strlen( string );

printf("\n %zd \n\n", n); /* %zd because n is of type size_t */

char sentence[] = "this is a sentence with words";
char *token = " ";
char *g;

g = strtok(sentence, token);

size_t y = strlen(g);

printf("the length of the first word in the sentence is %d\n\n", (int) y );

char *c_space = (char *) malloc( y * sizeof(char) + 1 );

if (c_space)
{
printf("got space for word\n\n");
}

int indexnewstring = (int) y + 1; /* (int) strlen( g ) + 1 */

char newstring[indexnewstring];

char *v = strcpy( newstring, g);
printf(" %s\n", v );

char sentence2[] = "this is a sentence with words";
g = strtok( sentence2, token );

while ( g != NULL )
{
printf("\n %s", g );
g = strtok( NULL, token );
}

printf("\n");

char sentence3[] = "C programming actually is the fun";

for( g = strtok(sentence3, token ); g != NULL; g = strtok( NULL, token ) )
printf (" %s\n", g );

return 0;
}

Questions: How do you free a pointer to a pointer of what it points to?

If you had not destroyed the value of a as noted above, you would
simply
free(a);
How would you free the pointer of the pointer a. (a+index)?

(a+index) is simply an address somewhere within whatever a points to.
It cannot be freed.

On the other hand, if you meant *(a+index), then:

As your code stands, a points to b. (a+index) is the address of
b[index]. Therefore, *(a+index) is an alias for the value b[index].
Since b[index] is a pointer that points to a string literal, it cannot
be freed. The only values that can be passed to free are NULL and the
address returned from malloc/calloc/realloc.

If your intent was to allocate space for an array of pointers and
then to allocate space for each of those pointers so they pointed to
strings, your code would look something like
char **a = malloc(...); /* allocate space for pointers */
for (i = 0; i < N; i++)
a = malloc(...); /* allocate space for strings */
/* obtain data for the k-th string */
strcpy(a[k], g); /* copy string to allocated space */
When it was time to free the space occupied by the strings and the
pointers, your code would look something like
for (i = 0; i < N; i++)
free(a); /*free each individual string */
free(a); /* free array of pointers */
Of course, you would do error checking on each of the calls to malloc.
strtok(), on my machine, seems to only take an array of characters. Is
the function suppose to string constants too.

Since strtok changes the string it points to (by inserting the '\0'
character in place of delimiter that marks the end of a token), it
cannot be used on a string literal. Any attempt to modify a string
literal invokes undefined behavior.
sen4 = {"this is a short sentence"};

Assuming you meant char *sentence4 = {...}, then the data sentence4
points to cannot be parsed by strtok.
 
B

Ben Bacarisse

char **a;
int numberOfPointers = 5;

a = (char **) malloc ( numberOfPointers * ( sizeof(char * ) ) );

if ( a!= NULL )
printf( "the array, a, points to declare space\n\n" );

char *b[] = { "one", "two", "three", "four", "five" };

a = b;

It's possible that you don't know what this assignment does. It only
replaces one pointer with another. The pointer value that used to be in
'a' is lost so you can no longer access the memory that was allocated.
in particular, you can't ever free it now.

<snip>
 
B

Ben Bacarisse

char **a;
int numberOfPointers = 5;

a = (char **) malloc ( numberOfPointers * ( sizeof(char * ) ) );
char *b[] = { "one", "two", "three", "four", "five" };
a = b;
to free the memory of what a's pointers point to would it be:
free((void *) a+index);

If 'a' did in fact point to (the start of) an array of pointers that
could be freed you'd write

free(a[index]);

If you try that with your program, it won't work because, while 'a' does
pointer to an array of pointers, they are not "freeable". a[0], a[1]
etc all point to statically allocated arrays of chars. These arrays get
made when you use string literals like "one" and "two". You can't free them.
 
S

Sharwan Joram

(e-mail address removed) writes:

char **a;
int numberOfPointers = 5;

a = (char **) malloc ( numberOfPointers * ( sizeof(char * ) ) );

if ( a!= NULL )
printf( "the array, a, points to declare space\n\n" );
char *b[] = { "one", "two", "three", "four", "five" };
a = b;



It's possible that you don't know what this assignment does. It only

replaces one pointer with another. The pointer value that used to be in

'a' is lost so you can no longer access the memory that was allocated.

in particular, you can't ever free it now.



<snip>

Hi,
It was fixed when i realized that I have not given the proper space in allocation of the double indirection pointer @ :
parameters = malloc(parametercount * sizeof(char *));

to
parameters = malloc((parametercount + 1) * sizeof(char *));
..
I learned lots of new stuff from you all guys during this discussion.

Thanks everyone for the help !!
 
B

Ben Bacarisse

Sharwan Joram said:
char **a;
int numberOfPointers = 5;

a = (char **) malloc ( numberOfPointers * ( sizeof(char * ) ) );

if ( a!= NULL )
printf( "the array, a, points to declare space\n\n" );

char *b[] = { "one", "two", "three", "four", "five" };

a = b;

It's possible that you don't know what this assignment does. It only
replaces one pointer with another. The pointer value that used to be in
'a' is lost so you can no longer access the memory that was allocated.
in particular, you can't ever free it now.
It was fixed when i realized that I have not given the proper
space in allocation of the double indirection pointer @ :

parameters = malloc(parametercount * sizeof(char *));

to
parameters = malloc((parametercount + 1) * sizeof(char *));

I think you are confused. You did have a problem allocating too few
pointers, but in that case parametercount was simply misnamed (or
misused) -- you'd counted delimiters between parameters, not parameters
themselves.

Anyway, none of this has anything to do with my remark above.

<snip>
 
I

Ike Naar

Only if the jarring is based on pure C language semantics. I think the
previous person was referring to the fact that for English speakers, the
sentence X equals Y, has a different grammatical implications than Y
equals X, as the first variable is the subject of the verb equals and
the second is the object of the verb, and linguistically, the subject of
the verb is more important and should naturally be the variable, not the
constant, as the subject is what is being tested and the object the
value being tested for. It is just the fact that equals has this funny
transitive property that makes swapping make sense programatically, even
if it doesn't really change what makes sense linguistically.

The order NULL == var is jarring because we have no need to test for the
properties of NULL, we know everything possible about it.

A mathematical formula is not English prose and should not be read as such.
 
G

gdotone

/* This program creates and uses pointers to pointer of type char,
pointer to arrays of char, malloc(), to allocate memory for
the pointer to pointer and 1-D arrays, strlen(), sizeof(),
and strtok(). Using those functions the program separates words,
in array of character arrays, and string constants. It places
those words in an allocated spaces. This program builds from
simple statements and ideas so not to overwhelm. */

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

int main( void )

char **a;
int numberOfPointers = 5;

a = (char **) malloc ( numberOfPointers * ( sizeof(char * ) ) );



The cast is unnecessary, and if you compile using C90, could mask an error.


if ( a!= NULL )
printf( "the array, a, points to declare space\n\n" );
char *b[] = { "one", "two", "three", "four", "five" };
a = b;
for ( int index = 0; index < 5; index++ )

printf( "%s\n\n", *(a+index) );



*(a+index) is exactly equivalent to a[index]. It only saves two

characters in typing, but it also makes it easier to read.

yes it is equivalent.

}
for ( int index = 0; index < 5; index++ )

printf( "%s\n\n", *(a+index) );

char *string = "word" ;
size_t n = strlen( string );
printf("\n %zd \n\n", n); /* %zd because n is of type size_t */
char sentence[] = "this is a sentence with words";
char *token = " ";
char *g;

g = strtok(sentence, token);



The second argument of strtok is a list of delimiters that are be used

for breaking the string up into tokens. Naming that list "token"

suggests a misunderstanding of some kind (except for entries in the

Obfuscated C contest).


ok, i see your point, next time i will use delimiter
The cast is unnecessary in C. sizeof(char) is inherently 1, so that

should be just y+1.

didn't know that.

You reserve space for the word, but then don't use it, and also don't

free() it, so you've got a memory leak. I presume this is related to

your question below, even though it involves neither 'a' nor 'index'.

no, not really.

The cast is unnecessary. You should only use casts when they are

necessary. Any time you read or write a cast in a piece of C code, you

should examine it carefully, because necessary casts can do dangerous

things, things that often shouldn't be done. When you insert unnecessary

casts in your code, you make it harder to treat the necessary casts with

the proper level of caution.


char newstring[indexnewstring];
char *v = strcpy( newstring, g);
printf(" %s\n", v );
char sentence2[] = "this is a sentence with words";
g = strtok( sentence2, token );

while ( g != NULL )

printf("\n %s", g );
g = strtok( NULL, token );
printf("\n");

char sentence3[] = "C programming actually is the fun";
for( g = strtok(sentence3, token ); g != NULL; g = strtok( NULL, token ) )
printf (" %s\n", g );

return 0;


Questions: How do you free a pointer to a pointer of what it points to?
How would you free the pointer of the pointer a. (a+index)?



I'm not sure I understand your question, because the answer seems to be

too simple to cause any confusion, and refers to a case that comes up

nowhere in the above code. The rule of thumb is that if you have



expression = malloc(count * sizeof *expression)



Then it should be matched by:



free(expression);


ok



Such matching pieces of code are sometime referred to metaphorically as

"bookend code". In the above code, you should somewhere have had



a[index] = malloc(count * sizeof *a[index]);



in which case the matching free should look like



free(a[index]);



Note that you should NOT free(a) until you've already called

free(a[index]) for every case where a[index] contains a pointer returned

by a call to malloc(). No such cases come up in your code above.



Does that answer your question? If not, could you explain the context of

the question more explicitly, preferably in the form of C code?


strtok(), on my machine, seems to only take an array of characters. Is
the function suppose to string constants too.
sen4 = {"this is a short sentence"};



No. strtok() writes to the array that it is parsing. Writing to the

array pointed at by a string literal has undefined behavior, so you

should definitely NOT write such code.


strtok() writes to an array?


thanks
 
K

Keith Thompson

(e-mail address removed) writes:

[huge snip]



Your articles are difficult to read, partly because you're using the

broken Google Groups interface to Usenet.



GG encourages (or at least fails to discourage) very long lines, and it

handles quoted text poorly. Due, I think, to an assumption that

newlines denote paragraph breaks rather than line breaks, quoted text

tends to be double-spaced -- and quoted quoted text tends to be

quadruple-spaced, and so on.
[...]

actually i'm just cutting and pasting because i have noticed my typos of the pass.

style, i can certainly tighten things up and drop much of the comments to help
those that are use a tighter style read it. that copying and pasting maybe adding a little
extra. i checked my editor, i thought it was set to 80 chars, it was not, i changed it to
72. i believe the code is less than 80 chars in width. comments are long winded and longer.

hey, thanks i will repost. let know if it better.

Your quoted text is still double-spaced; see above.

This is the fault of the broken Google Groups interface (years of
complaints have not prompted Google to fix this), but you should be
able to avoid the problem. Either delete the blank lines yourself,
or use an Usenet interface other than Google Groups.
 
J

James Kuyper

On 08/26/2013 10:08 AM, David Brown wrote:
....
The "Yoda condition" is the habit of writing "if (1 == a)" rather than
"if (a == 1)", so that typos will lead to compiler errors - "if (1 = a)"
is a syntax error, while "if (a = 1)" is legal C and can be accepted by
the compiler.

However, that assumes you either have a very poor compiler (and no lint
tool to back it up), or you don't know how to use it properly. Unless
you are masochistic and enjoy finding hard-to-debug errors in your code,
you let your compiler do a lot of static error checking.

I don't use Yoda-conditions, but I appreciate the arguments of those
that do. I don't like to rely on diagnostics that are not mandated by
the standard, and the ones you're talking about aren't. I do prefer
compilers that provide such warnings.

....
In my opinion, it is better to do proper static error checking to
eliminate the risk of such typos, rather than to write your code backwards.

The code, as such, is neither forwards nor backwards. The idea that
there's a preferred order to the arguments of == has nothing to do with
any aspect of C itself; it seems to be based in linguistic preferences.
I share those preferences, but I wouldn't elevate them to issues of code
correctness, by calling the other order "backwards". I wouldn't be
surprised to find that people whose native language is not English might
find the "backwards" order more reasonable.
 
G

gdotone

(e-mail address removed) writes:

[huge snip]



Your articles are difficult to read, partly because you're using the

broken Google Groups interface to Usenet.



GG encourages (or at least fails to discourage) very long lines, and it

handles quoted text poorly. Due, I think, to an assumption that

newlines denote paragraph breaks rather than line breaks, quoted text

tends to be double-spaced -- and quoted quoted text tends to be

quadruple-spaced, and so on.


[...]



actually i'm just cutting and pasting because i have noticed my typos of the pass.
style, i can certainly tighten things up and drop much of the comments to help
those that are use a tighter style read it. that copying and pasting maybe adding a little
extra. i checked my editor, i thought it was set to 80 chars, it was not, i changed it to
72. i believe the code is less than 80 chars in width. comments are long winded and longer.

hey, thanks i will repost. let know if it better.



Your quoted text is still double-spaced; see above.



This is the fault of the broken Google Groups interface (years of

complaints have not prompted Google to fix this), but you should be

able to avoid the problem. Either delete the blank lines yourself,

or use an Usenet interface other than Google Groups.



--

Keith Thompson (The_Other_Keith) (e-mail address removed) <http://www.ghoti.net/~kst>

Working, but not speaking, for JetHead Development, Inc.

"We must do something. This is something. Therefore, we must do this."

-- Antony Jay and Jonathan Lynn, "Yes Minister"

i don't see that on my end. your post are double spaced.
 
J

James Kuyper

strtok() writes to an array?

Yes, it's first argument is an input/output pointer. It replaces the
first delimiter after each token in the input string with a '\0'.

char sen5[] = "this is a short sentence";

Calling strtok(sen5, " ") would set sen5[4] to '\0'. If your code then
calls strtok(NULL, " "), it would set sen5[7] to '\0'. If you called
strtok("this is a short sentence", " "), it would attempt to do the same
thing, but attempting to write to the array pointed at by a string
literal would render the behavior of your program undefined.
 
K

Keith Thompson

Ike Naar said:
James Kuyper said:
On 08/24/2013 03:05 PM, Sharwan Joram wrote: [...]
if ( NULL == parameters[parametercount]){

This is what's known as a "Yoda conndition"
<http://en.wikipedia.org/wiki/Yoda_Conditions>. I know that a lot of
programmers like them, and for somewhat valid reasons, but personally I
find them jarring and unnecessary. Personally, I'd write that as:

if (parameters[parametercount] == NULL) {

Does it matter? The == operator is symmetric, (X==Y) == (Y==X).

If (X==Y) is jarring and unnecessary, then, for symmetry reasons
(Y==X) is unnecessary and jarring.
[...]

Yes, it matters *to me* (and to plenty of other people). "==" is
commutative as far as the language is concerned, but code should be
written both for the compiler and for the human reader.

X==Y is a poor example for this, since X==Y and Y==X are pretty much
equally readable. The problem (for me) is when programmers write things
like:
if (0 == strcmp(s1, s2))
rather than
if (strcmp(s1, s2) == 0)

When comparing a computed value to a constant, I'm asking a question
about the computed value: (Is it equal to this constant?) You can
ask a question about a constant: (Is it equal to this computed
value?), but I personally find that to be an awkward way to ask
the same question.

If you find (strcmp(s1, s2) == 0) just as readable and natural as
(0 == strcmp(s1, s2)), that's great for you; apparently your brain
works just a little bit differently than mine.

If your only criterion for choosing between two different ways
of writing something is that they have the same language-level
semantics, that should mean you have no preference between arr
and i[arr], or between

if (foo) {
/* ... */
}

and

if (!foo); else {
/* ... */
}

but I know which I'd rather see.

I know why Yoda conditions are used, and it's a valid reason.
But would you even consider writing

if (0 == strcmp(s1, s2))

if it weren't for the "==" vs. "=" issue?
 

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
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top