Little problem with a delirant program

A

Army1987

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
char *_(char *str1, char *str2)
{
char *res;
res = malloc((strlen(str1)+strlen(str2))*sizeof(char));
strcpy(res, str1);
strcpy(res+strlen(str1), str2);
return res;
}

int main(void)
{
char a[] = "\nHey man look at me rockin' now\nI'm on the ";
char b[] = "Danny and Lisa";
char c[] = "\nThey take me away from";
char *d = _(_(a,"radio"),_(a,"video"));
char *e = _(d,_(" with ",b));
char *g = _("\nThe strangest places\nSweet ",b);
char *h = _(c,g);
char *i = _(_(h,c),_(h,c));
char *j = _(e,i);
char *k = _(_(d,j),_(j,e));
char *l = _(_(k,h),_(d,e));
puts(++l); /* ++l gets rid of the spurious newline character at the
beginning */
return 0;
}

Why does this program add a spurious '1' after each occurrence of the last
line of the chorus? (i.e. "I'm on the video with Danny and Lisa1").
(I said it was delirant... But I fear that for copyright problems I won't be
able to sumbit a modification of this to the next IOCCC...)
T.I.A.

--
#include <stdio.h>
main()
{
printf("\n\n--\nArmy1987");
}
 
E

Eric Sosman

Army1987 said:
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
char *_(char *str1, char *str2)

Don't do that. Identifiers beginning with `_' are
reserved. There are a few contexts in which they are not
reserved, but this isn't one of them.
{
char *res;
res = malloc((strlen(str1)+strlen(str2))*sizeof(char));
strcpy(res, str1);
strcpy(res+strlen(str1), str2);

This is probably where your program goes off the rails;
perhaps one line earlier if str2 has zero length. I thought
this matter would be covered in the FAQ -- but perhaps it's
just a Frequently Committed Error rather than a Frequently
Asked Question, since the very asking of the question implies
awareness of the issue.

Anyhow, the immediate error is that a string whose length
is N characters requires N+1 bytes of storage.
return res;
}

int main(void)
{
char a[] = "\nHey man look at me rockin' now\nI'm on the ";
char b[] = "Danny and Lisa";
char c[] = "\nThey take me away from";
char *d = _(_(a,"radio"),_(a,"video"));
char *e = _(d,_(" with ",b));
char *g = _("\nThe strangest places\nSweet ",b);
char *h = _(c,g);
char *i = _(_(h,c),_(h,c));
char *j = _(e,i);
char *k = _(_(d,j),_(j,e));
char *l = _(_(k,h),_(d,e));
puts(++l); /* ++l gets rid of the spurious newline character at the
beginning */
return 0;
}

Why does this program add a spurious '1' after each occurrence of the last
line of the chorus? (i.e. "I'm on the video with Danny and Lisa1").
(I said it was delirant... But I fear that for copyright problems I won't be
able to sumbit a modification of this to the next IOCCC...)

It wouldn't win. The IOCCC seeks obfuscations far more
original than just using an unusual name, especially an unusual
name that isn't yours to use.
 
M

Malcolm McLean

Army1987 said:
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
char *_(char *str1, char *str2)
{
char *res;
res = malloc((strlen(str1)+strlen(str2))*sizeof(char));
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
No room for terminating nul.
strcpy(res, str1);
strcpy(res+strlen(str1), str2);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Undefined behaviour here.
return res;
}

int main(void)
{
char a[] = "\nHey man look at me rockin' now\nI'm on the ";
char b[] = "Danny and Lisa";
char c[] = "\nThey take me away from";
char *d = _(_(a,"radio"),_(a,"video"));
char *e = _(d,_(" with ",b));
char *g = _("\nThe strangest places\nSweet ",b);
char *h = _(c,g);
char *i = _(_(h,c),_(h,c));
char *j = _(e,i);
char *k = _(_(d,j),_(j,e));
char *l = _(_(k,h),_(d,e));
puts(++l); /* ++l gets rid of the spurious newline character at the
beginning */
return 0;
}

Why does this program add a spurious '1' after each occurrence of the last
line of the chorus? (i.e. "I'm on the video with Danny and Lisa1").
(I said it was delirant... But I fear that for copyright problems I won't
be able to sumbit a modification of this to the next IOCCC...)
T.I.A.

--
#include <stdio.h>
main()
{
printf("\n\n--\nArmy1987");
}
 
A

Army1987

I've found the problem. For the memory allocated by the function _(str1,
str2) to contain the concatenation of str1 and str2, its size should be
strlen(str1) + strlen(str2) + 1, as one byte is needed to contain the
terminator '\0' character.

So I replaced the assignment in the function body with:
res = malloc((strlen(str1)+strlen(str2)+1)*sizeof(char));

Probably, in the former version of the program the '\0' byte after one of
these strings was somehow overwritten as it was not "allotted" for that
string.

BTW, I meant "delirious". I should have checked my English besides my C...
 
A

Army1987

It wouldn't win. The IOCCC seeks obfuscations far more
original than just using an unusual name, especially an unusual
name that isn't yours to use.

I used that just because it was the shortest identifier which couldn't clash
with a letter (as I didn't know beforehand how many letters I had to use).
Of course I could just use a capital letter, but I didn't know about
reserved identifiers, and I thougth _ was cooler... ;-)
Of course, if I were really going to submit it to IOCCC, I'd brutally deface
it first... (I was just joking, I started learning C just about two months
ago... And I've seen some programs by the past winners of IOCCC and I really
think some of them really need to get a life...)
 
M

Martin Ambuhl

Army1987 said:
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
char *_(char *str1, char *str2)
^^^
very, very naughty. Don't do this. It is evil.
{
char *res;
res = malloc((strlen(str1)+strlen(str2))*sizeof(char));

Not only is sizeof(char) superfluous here (it's 1 by definition),
you don't allocate enough space:
res = malloc(strlen(str1) + strlen(str2) + 1);
And, of course, you should check the return value from malloc.

strcpy(res, str1);
strcpy(res+strlen(str1), str2);
return res;
}

int main(void)
{
char a[] = "\nHey man look at me rockin' now\nI'm on the ";
char b[] = "Danny and Lisa";
char c[] = "\nThey take me away from";
char *d = _(_(a,"radio"),_(a,"video"));
char *e = _(d,_(" with ",b));
char *g = _("\nThe strangest places\nSweet ",b);
char *h = _(c,g);
char *i = _(_(h,c),_(h,c));
char *j = _(e,i);
char *k = _(_(d,j),_(j,e));
char *l = _(_(k,h),_(d,e));
puts(++l); /* ++l gets rid of the spurious newline character at the
beginning */
return 0;

Are you _sure_ you want to return before freeing all those arrays
that your (incorrectly) allocated?
}

Why does this program add a spurious '1' after each occurrence of the last
line of the chorus?

Since your allocation is broken, you're unlucky that your program didn't
crash instead.
(i.e. "I'm on the video with Danny and Lisa1").
(I said it was delirant... But I fear that for copyright problems I won't be
^^^^^^^^
What language is this a word in? And when did you say it? What
does it mean?
able to sumbit a modification of this to the next IOCCC...)

Please don't submit broken or illegal code to IOCCC. The woeld doesn't
need any more of either.

Bite me.
 
A

Army1987

Are you _sure_ you want to return before freeing all those arrays that
your (incorrectly) allocated?
Isn't my OS supposed to free them all immediately after main() returns?
(I refer to the corrected version, with
res = malloc(strlen(str1)+strlen(str2)+1);
and maybe even
if (res==NULL) exit(EXIT_FAILURE);
now.)

^^^^^^^^
What language is this a word in? And when did you say it? What
does it mean?

I meant "delirious", sorry. I said it in the object line.
 
O

Old Wolf

Don't do that. Identifiers beginning with `_' are
reserved. There are a few contexts in which they are not
reserved, but this isn't one of them.

I thought such identifiers were only reserved if they started
with _ followed by an uppercase letter (or another _).
 
M

Malcolm McLean

Army1987 said:
Isn't my OS supposed to free them all immediately after main() returns?
(I refer to the corrected version, with
res = malloc(strlen(str1)+strlen(str2)+1);
and maybe even
if (res==NULL) exit(EXIT_FAILURE);
now.)
If an OS doesn't free memory on exit either
You are running a useless operating system that should be traded in
immediately
or
You are on some small system that will only run a limited subset of
programs, and isn't meant to be a general-purpose computer.

However it is a good habit to free memory after you are done with it. In big
programs it is essential.
 
P

pete

Old said:
I thought such identifiers were only reserved if they started
with _ followed by an uppercase letter (or another _).

The rules are complicated enough so that I just simply
avoid writing identifiers that start with underscores.

N869
7.1.3 Reserved identifiers
[#1]
-- All identifiers that begin with an underscore are
always reserved for use as identifiers with file scope
in both the ordinary and tag name spaces.
 
M

Martin Ambuhl

Army1987 said:
Isn't my OS supposed to free them all immediately after main() returns?

There is nothing in C requiring your OS to do anything of the sort.
Whether your OS does so is, obviously, OS-dependent, and discussions of
that OS (or about the virtues of various OSs, as in Mr. McLean's post)
are completely off-topic here.
[...]
I meant "delirious", sorry. I said it in the object line.

If something in your headers is somehow germane to your post, that
something belongs in the body of the post. Anyone who has used
newsgroups for more than ten minutes knows how worthless subject headers
are for anything substantive, including the subject of the post. Many,
perhaps most users of newsgroups use them at most to ignore threads that
they already know to be worthless.
 
E

Eric Sosman

Old said:
I thought such identifiers were only reserved if they started
with _ followed by an uppercase letter (or another _).

You have mixed up a couple different sets of identifiers
that are reserved in a couple different scopes. A few quiet
moments with the Standard might set your mind at rest.
 
C

CBFalconer

Martin said:
Army1987 wrote:
.... snip ...


If something in your headers is somehow germane to your post, that
something belongs in the body of the post. Anyone who has used
newsgroups for more than ten minutes knows how worthless subject
headers are for anything substantive, including the subject of the
post. Many, perhaps most users of newsgroups use them at most to
ignore threads that they already know to be worthless.

Such as this one.

--
<http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>
<http://www.securityfocus.com/columnists/423>

"A man who is right every time is not likely to do very much."
-- Francis Crick, co-discover of DNA
"There is nothing more amazing than stupidity in action."
-- Thomas Matthews
 
A

Army1987

Isn't my OS supposed to free them all immediately after main() returns?
There is nothing in C requiring your OS to do anything of the sort.
Whether your OS does so is, obviously, OS-dependent, and discussions of
that OS (or about the virtues of various OSs, as in Mr. McLean's post) are
completely off-topic here.
[...]
<OT>
Of course not, but simply I can't see the reason why an OS should leave
memory allocated for a program which has already terminated, regardless of
what language it is written in.
</OT>
BTW, some implementation of free() do not give the memory back to the OS,
they just free it for new malloc()s, then if my OS is so cretinous and my
implementation of free() works this way (altho' anybody who's written such
an implementation for such an OS would be a complete idiot), freeing the
memory from within the program just before exiting would be no use. Anyway,
I do free memory allocated in a function other than main() before returning
if I know that it won't be needed by the caller.
If something in your headers is somehow germane to your post, that
something belongs in the body of the post. Anyone who has used newsgroups
for more than ten minutes knows how worthless subject headers are for
anything substantive, including the subject of the post. Many, perhaps
most users of newsgroups use them at most to ignore threads that they
already know to be worthless.

Yes, but that was just a humorous comment...
 
C

Clever Monkey

Army1987 said:
I used that just because it was the shortest identifier which couldn't clash
with a letter (as I didn't know beforehand how many letters I had to use).
Of course I could just use a capital letter, but I didn't know about
reserved identifiers, and I thougth _ was cooler... ;-)
Of course, if I were really going to submit it to IOCCC, I'd brutally deface
it first... (I was just joking, I started learning C just about two months
ago... And I've seen some programs by the past winners of IOCCC and I really
think some of them really need to get a life...)
Hacking at the limits of a system, even to the point of making
unreadable programs, is a time-honoured way to express creativity and
really learn the system.

Would you say that someone learning to express themselves through prose
or poetry, "you need to get a life?" I'm guessing not, or not just
/because/ they were practicing the craft of writing, even if that
writing was opaque and stretched the rules of spelling and grammar to
their limits.

The IOCCC is even more of a challenge because you have to make prose
that is acceptable by a compiler and runtime environment.

You probably need a little more time on Dagobah before striking out on
your own to strike at the heart of the IOCCC.
 

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

Forum statistics

Threads
473,780
Messages
2,569,608
Members
45,252
Latest member
MeredithPl

Latest Threads

Top