Another Understanding Pointers Question

M

Martin Dickopp

Possibly, and possibly not; in any case, at the end of the program it is
hardly likely to matter a lot, is it?

That depends on the situation. In situations where processes terminate
very often [*], it may take a significant amount of CPU.

Martin


[*] A common example is a server program which creates a new process for
every incoming request.
 
D

Dan Pop

In said:
Possibly, and possibly not; in any case, at the end of the program it is
hardly likely to matter a lot, is it?

To some people, "stealing" CPU cycles from programs that are still
running for no *good* reason DOES matter.

Dan
 
A

Alex Monjushko

Possibly, and possibly not; in any case, at the end of the program it is
hardly likely to matter a lot, is it?

If a program unnecessarily takes N seconds to terminate, it is likely
to matter for large enough value of N.
 
M

Michael Wojcik

Possibly, and possibly not; in any case, at the end of the program it is
hardly likely to matter a lot, is it?

There are plenty of situations where program-exit latency can be an
issue. It may simply be a usability or quality-of-experience one,
where it's just a matter of making a user wait longer than necessary;
but it may also affect overall system performance, if other tasks
need to wait for the exiting program.

Another possible disadvantage is that explicitly freeing all allocated
areas at the end of the program increases maintenance effort (because
a maintainer who alters the program's memory allocation must now take
that into account), and introduces a source of maintenance bugs (a
maintainer adds a free for an area elsewhere in the logic, not realizing
that the program will attempt to free it again at exit).

In general, the arguments for "automatic free on exit" (for implementa-
tions that do so) are similar to those in favor of garbage collection.

That's not to say that any of those arguments are necessarily compelling,
just that there are potentially disadvantages, under some rubrics, for
explicitly freeing everything before exiting.

--
Michael Wojcik (e-mail address removed)

Pocket #16: A Ventriloquist's "Helper" -- Recordings for Divers Occasions,
especially cries to put in the mouths of enemies -- "God Bless Captain
Vere!" "Les jeux sont faits!" &c. -- Joe Green
 
M

Materialised

Materialised said:
Hi everyone,
I seen the post by Rob Morris, and thought that I would double check
that I was using pointers in the correct way. So I written the following
string functions to test. I know soem can be iumplimented using the
standard libary, but I just wanted to test writing my own functions.
They work ok, but I would like some feed back on any issues you can see
with them etc
I would like to thank everyone for their comments and suggestions. I
have now modified the code to include sanity checking, this is the
modified version,

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

char *left(char *string, int count)
{
char *p;
int i;
if(strlen(string) <= 0 ) {
p = NULL;
return p;
}
if(count > strlen(string)) {
p = NULL;
return p;
}
if(!count) {
p = NULL;
return p;
}
p = malloc((count * sizeof(char)+1));
if(!p){
p = NULL;
return p;
}


for(i = 0; i <= count -1; i++) {
p = string;
}
p[i++] = '\0';

return p;

}

char *right(char *string, int count)
{
char *p;
int len, i, j = 0;
if(strlen(string) <= 0 ) {
p = NULL;
return p;
}
if(count > strlen(string)) {
p = NULL;
return p;
}
if(!count) {
p = NULL;
return p;
}
p = malloc((count * sizeof(char)+1));
if(!p){
p = NULL;
return p;
}
len = strlen(string);
for(i = (len - count); i <= len; i++){
p[j] = string;
j++;
}

p[j++] = '\0';
return p;

}

char *chreplace(char *string, int count, char rep)
{
char *p;
if(strlen(string) <= 0 ) {
p = NULL;
return p;
}
if(count > strlen(string)) {
p = NULL;
return p;
}
if(!count){
p = NULL;
return p;
}
if(!rep) {
p = NULL;
return p;
}
p = malloc((count * sizeof(char)+1));
if(!p){
p = NULL;
return p;
}
count--;
strcpy(p, string);
p[count] = rep;

return p;
}

char *section(char *string, int from, int to)
{
char *p;
int i, j = 0;
if(strlen(string) <= 0) {
p = NULL;
return p;
}
if(!from) {
p = NULL;
return p;
}
if(!to) {
p = NULL;
return p;
}
if(from > strlen(string)) {
p = NULL;
return p;
}
if(to > strlen(string)){
p = NULL;
return p;
}
p = malloc(((to - from) * sizeof(char)+1));
if(!p){
p = NULL;
return p;
}
for( i = from; i <= to; i++) {
p[j] = string;
j++;
}
p[j++] = '\0';

return p;
}





int main(void)
{
char blah[] = "abcdefghijklm";
char *test;
char *test2;
char *test3;
char *test4;

test = left(blah, 10);
test2 = right(blah, 10);
test3 = chreplace(blah, 2, 'Q');
test4 = section(blah, 4, 10);
if(test)
puts(test);
if(test2)
puts(test2);
if(test3)
puts(test3);
if(test4)
puts(test4);
free(test);
free(test2);
free(test3);
free(test4);
return 0;
}

Any comments or advice on this version are more than welcome.


--
 
O

Old Wolf

Materialised said:
I would like to thank everyone for their comments and suggestions. I
have now modified the code to include sanity checking, this is the
modified version,

Your code works but there is a lot of redundant code.
I have commented below on your left() function only (similar comments
will apply to the rest of your code).
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char *left(char *string, int count)
{
char *p;
int i;
if(strlen(string) <= 0 ) {
p = NULL;
return p;

return NULL;

Out of interest, what motivated you to write "p = NULL; return p;" ?
}
if(count > strlen(string)) {
p = NULL;
return p;
}
if(!count) {
p = NULL;
return p;
}

You do not check if count is less than 0 (which would produce
undefined behaviour), and you do not check if string is NULL.
Both of these checks would usually be included in "sanity checks".

On the other hand, you do return NULL if count is exactly zero.
It might be more sensible to return a blank string in this case
(but then again it might not -- your call).

You do strlen(string) twice in this function, which is a waste.
In fact you do not need to test if it is less than or equal to zero,
because it cannot be negative, and your function will work correctly
if it is zero (because then one of the checks on "count" will fail).

You could do the checks like this:

if (count <= 0) /* or (count < 0) if you want to allow 0 */
return NULL;

if (string == NULL) /* (optional) */
return NULL;

if (count > strlen(string))
return NULL;
p = malloc((count * sizeof(char)+1));

p = malloc((count+1) * sizeof(char));

You've discussed why you like to have "sizeof(char)" instead of "1":
so that the form of the malloc() call is the same for whichever type
you are using. However your code would have been wrong if it were
changed to another type, eg:

wchar_t *w;
w = malloc(count * sizeof(wchar_t) + 1);

because you want (count + 1) wchars, not (count) wchars and 1 byte.
if(!p){
p = NULL;
return p;
}

p is already NULL so why set it to NULL again ??
for(i = 0; i <= count -1; i++) {

for (i = 0; i < count; i++)

Although it means the same thing, this is more idiomatic (ie. more
readable) to the majority of C programmers.
p = string;
}
p[i++] = '\0';


i is never used after this statement, so incrementing it is a waste
of time.

Also possible (more efficient, and not requiring another variable) was:

memcpy(p, string, count);
p[count] = '\0';
return p;

}

Here is how I might have written that function (note, this is not to
say that you should do it my way -- just to give you some more ideas)

char *left( char *string, int count )
{
char *p;

if ( !string || count < 0 || count > strlen(string) )
return NULL;

p = malloc(count+1);
if (p)
{
memcpy(p, string, count);
p[count] = '\0';
}
return p;
}
 

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,818
Members
47,367
Latest member
mahdiharooniir

Latest Threads

Top