473,396 Members | 2,068 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,396 software developers and data experts.

malloc's strang behavior

Hi all

I'm writting a simple code to solve an ACM problem
(http://acm.uva.es, it is the problem #468). In its code I have the
following fragment:

freq = calcfreq(hashfreq, strfreq, input);
printf("before malloc: %s (%p)\n", input+INPUTLEN);
hchars = (char *)malloc(freq*sizeof(char));
schars = (char *)malloc(freq*sizeof(char));
printf("after malloc: %s\n (%p)\n", input+INPUTLEN);

Since input has nothing to do with the mallocs I expected it would be
unchanged but this isn't happening. Suppouse input points to the
string "xxxxyy", this fragment of code outputs like this:

before malloc: xxxxyy (0x8049ef0)
after malloc: xxxx (0x8049ef0)

Anyone got a clue on what could be happening here?
Thanks in advance

--
Gustavo G. Rondina
http://gustgr.freeshell.org
Nov 14 '05 #1
11 1607
Gustavo G. Rondina <gu****@brlivre.org> writes:
Hi all

I'm writting a simple code to solve an ACM problem
(http://acm.uva.es, it is the problem #468). In its code I have the
following fragment:

freq = calcfreq(hashfreq, strfreq, input);
printf("before malloc: %s (%p)\n", input+INPUTLEN);
hchars = (char *)malloc(freq*sizeof(char));
schars = (char *)malloc(freq*sizeof(char));
printf("after malloc: %s\n (%p)\n", input+INPUTLEN);

Since input has nothing to do with the mallocs I expected it would be
unchanged but this isn't happening. Suppouse input points to the
string "xxxxyy", this fragment of code outputs like this:

before malloc: xxxxyy (0x8049ef0)
after malloc: xxxx (0x8049ef0)

Anyone got a clue on what could be happening here?


In both printf calls, the format string has a "%s" and a "%p"
conversion, but you only provide one addtional argument rather than
two. I wouldn't necessarily expect this to cause the specific problem
you're seeing, but you should definitely fix it before attempting to
proceed any further.

Casting the result of malloc() is unnecessary, and can mask errors
such as forgetting the "#include <stdlib.h>". Also sizeof(char) is
always 1, by definition. Thus the two assignments can be simplified
to

hchars = malloc(freq);
schars = malloc(freq);

Finally, if you still have questions after making these changes,
please show us a small, complete, compilable program that exhibits the
problem. We can't see the declarations of your variables, and we
can't tell whether you've included the proper headers. That makes it
difficult to help you. (And there's a fairly good chance that you'll
solve the problem yourself while paring it down to something small
enough to post.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #2
On 21 Jul 2004 00:52:54 GMT, Gustavo G. Rondina <gu****@brlivre.org>
wrote:
Hi all

I'm writting a simple code to solve an ACM problem
(http://acm.uva.es, it is the problem #468). In its code I have the
following fragment:

freq = calcfreq(hashfreq, strfreq, input);
printf("before malloc: %s (%p)\n", input+INPUTLEN);
hchars = (char *)malloc(freq*sizeof(char));
schars = (char *)malloc(freq*sizeof(char));
printf("after malloc: %s\n (%p)\n", input+INPUTLEN);

Since input has nothing to do with the mallocs I expected it would be
unchanged but this isn't happening. Suppouse input points to the
string "xxxxyy", this fragment of code outputs like this:

before malloc: xxxxyy (0x8049ef0)
after malloc: xxxx (0x8049ef0)

Anyone got a clue on what could be happening here?
Thanks in advance


I give up. How do you get two variables formatted in your output (to
match the two format specifiers) when you have only one argument
following the format string?

Why are you casting the return from malloc? If it is to silence a
compiler diagnostic about converting int to char* then you have
invoked undefined behavior by not providing the prototype for malloc.
If it is to silence a compiler diagnostic about converting void* to
int* then you are compiling it as C++ and this is the wrong group.

Since sizeof(char) is always 1, you can remove that expression from
the arguments to malloc.

Can you provide a compilable example that exhibits the behavior?
<<Remove the del for email>>
Nov 14 '05 #3
Sorry guys, copy and paste problem. Here is the correct code fragment:

freq = calcfreq(hashfreq, strfreq, input);
printf("%s (%p)\n", input+INPUTLEN, input+INPUTLEN);
hchars = (char *)malloc(freq*sizeof(char));
schars = (char *)malloc(freq*sizeof(char));
printf("%s (%p)\n", input+INPUTLEN, input+INPUTLEN);

The problem it is still there. The output follows:

before malloc: xxxxyy (0x8049ef0)
after malloc: xxxx (0x8049ef0)

The full code is avaliable at: http://www.brlivre.org/c/468.c

If anyone have spare time I would appreciate some help.
Thanks,
Gustavo

PS. this is not any kind of homework, I code (at least I try to) as a
hobby.
Nov 14 '05 #4
Sorry about the mess, here is the _right_ code:

http://www.brlivre.org/c/468.c

This code isn't finished yet, I'll try to fix this problem before
going on. The problem seems to be on this code fragment:

freq = calcfreq(hashfreq, strfreq, input);
printf("before malloc: %s (%p)\n", input+INPUTLEN, input+INPUTLEN);
hchars = (char *)malloc(freq*sizeof(char));
schars = (char *)malloc(freq*sizeof(char));
printf("after malloc: %s (%p)\n", input+INPUTLEN, input+INPUTLEN);

Here is what I got:

$ ./468
1

aaaaab
xxxxxxyyy
before malloc: xxxxxxyyy (0x8049f00)
after malloc: xxxx (0x8049f00)
$

Anyone got a clue?
Thanks (again)
--
Gustavo G. Rondina
http://gustgr.freeshell.org
Nov 14 '05 #5
Gustavo G. Rondina wrote:
Hi all

I'm writting a simple code to solve an ACM problem
(http://acm.uva.es, it is the problem #468). In its code I have the
following fragment:

freq = calcfreq(hashfreq, strfreq, input);
We don't know, of course, what any of freq, calcfreqm hashfreq, (badly
named) strfreq, or input are.
printf("before malloc: %s (%p)\n", input+INPUTLEN);
This is nonsense. The specification string expects two more arguments
(for three in all). You give only one more. Luckily for you, we can't
tell if you forgot to cast the argument corresponding to "%p" to
(void *).
hchars = (char *)malloc(freq*sizeof(char));
schars = (char *)malloc(freq*sizeof(char));
At this point we know for sure you have not followed normal usenet
etiquette and lurked before posting, or checked the archives, or checked
the FAQ. You would do better with
hchars = malloc(freq);
schars = malloc(freq);
or
hchars = malloc(freq * sizeof *hchars);
schars = malloc(freq * sizeof *schars);
Of course you should #include <stdlib.h> and check the returned values
from malloc for success.
printf("after malloc: %s\n (%p)\n", input+INPUTLEN);
This is nonsense, again.
Since input has nothing to do with the mallocs I expected it would be
unchanged but this isn't happening. Suppouse input points to the
string "xxxxyy", this fragment of code outputs like this:

before malloc: xxxxyy (0x8049ef0)
after malloc: xxxx (0x8049ef0)

Anyone got a clue on what could be happening here?


It appears that the array which either is 'input' or is pointed to by
'input' has a size of 4 and was initialized incorrectly, perhaps with
char input[4]="xxxx";
Somehow you have gained a '\0' in the first char _following_ input in
the process of allocating space.

All this is guessing, since you have not not posted compilable code, but
have posted something that is *not* your real code, else the output
would not be what you claim.
Nov 14 '05 #6
Gustavo G. Rondina wrote:
Sorry guys, copy and paste problem. Here is the correct code fragment:

freq = calcfreq(hashfreq, strfreq, input);
printf("%s (%p)\n", input+INPUTLEN, input+INPUTLEN); ^^^^^^^^^^^^^^
This is almost certainly wrong. Provide the cast (void *) to the type
%p expects.
hchars = (char *)malloc(freq*sizeof(char));
schars = (char *)malloc(freq*sizeof(char));
printf("%s (%p)\n", input+INPUTLEN, input+INPUTLEN);

The problem it is still there. The output follows:

before malloc: xxxxyy (0x8049ef0)
after malloc: xxxx (0x8049ef0)

The full code is avaliable at: http://www.brlivre.org/c/468.c


Come on: do the small amount of work necessary to produce a compilable
minimal program that exhibits your problem. If it's too much trouble
for you to do that, it's too much trouble for us. Post the resulting
code here. No one here has reason to go clicking on wesites we have no
reason to trust.
Nov 14 '05 #7
On 21 Jul 2004 01:48:28 GMT, Gustavo G. Rondina <gu****@brlivre.org>
wrote:
Sorry guys, copy and paste problem. Here is the correct code fragment:

freq = calcfreq(hashfreq, strfreq, input);
printf("%s (%p)\n", input+INPUTLEN, input+INPUTLEN);
hchars = (char *)malloc(freq*sizeof(char));
schars = (char *)malloc(freq*sizeof(char));
printf("%s (%p)\n", input+INPUTLEN, input+INPUTLEN);

The problem it is still there. The output follows:

before malloc: xxxxyy (0x8049ef0)
after malloc: xxxx (0x8049ef0)

The full code is avaliable at: http://www.brlivre.org/c/468.c

If anyone have spare time I would appreciate some help.


Your readinput function invokes undefined behavior. It attempts to
read twice as many strings as you allocate space for.

Your calcfreq function will invoke undefined behavior if any of your
input contains anything other than lowercase ASCII characters since
your offset into the arrays will be negative.

The readinput error can very easily break your run-time memory
management and cause subsequent calls to malloc to do very strange
things.
<<Remove the del for email>>
Nov 14 '05 #8
Gustavo G. Rondina wrote:
Sorry about the mess, here is the _right_ code:

http://www.brlivre.org/c/468.c

This code isn't finished yet, I'll try to fix this problem before
going on. The problem seems to be on this code fragment:

freq = calcfreq(hashfreq, strfreq, input);
printf("before malloc: %s (%p)\n", input+INPUTLEN, input+INPUTLEN);
hchars = (char *)malloc(freq*sizeof(char));
schars = (char *)malloc(freq*sizeof(char));
printf("after malloc: %s (%p)\n", input+INPUTLEN, input+INPUTLEN);


No, the problem is that you've written past the end of `input`
somewhere, since if you mallocate an extra 1000 bytes for it,
the problem goes away.

Given that the code is horribly opaque (eg why on Earth do you write
`*(E+F)` for `E[F]`, what is 97 when it's a home, what it is all *for*?),
motivation for proceeding further in the analysis escapes me.

--
Chris "electric hedgehog" Dollin
C FAQs at: http://www.faqs.org/faqs/by-newsgrou...mp.lang.c.html
C welcome: http://www.angelfire.com/ms3/bchambl...me_to_clc.html
Nov 14 '05 #9
Gustavo G. Rondina <gu****@brlivre.org> wrote in message news:<2m************@uni-berlin.de>...
Sorry about the mess, here is the _right_ code:

http://www.brlivre.org/c/468.c

This code isn't finished yet, I'll try to fix this problem before
going on. The problem seems to be on this code fragment:

freq = calcfreq(hashfreq, strfreq, input);
printf("before malloc: %s (%p)\n", input+INPUTLEN, input+INPUTLEN);
hchars = (char *)malloc(freq*sizeof(char));
schars = (char *)malloc(freq*sizeof(char));
printf("after malloc: %s (%p)\n", input+INPUTLEN, input+INPUTLEN);

Here is what I got:

$ ./468
1

aaaaab
xxxxxxyyy
before malloc: xxxxxxyyy (0x8049f00)
after malloc: xxxx (0x8049f00)
$

Anyone got a clue?
Thanks (again)

The most likely explanation is that you have corrupted memory
elsewhere in your program, and you are only seeing the result here.
For instance if the storage pointed to by "input" has already being
freed.
Nov 14 '05 #10
[snips]

On Wed, 21 Jul 2004 01:48:28 +0000, Gustavo G. Rondina wrote:
The full code is avaliable at: http://www.brlivre.org/c/468.c


Actually, it's not. However, a little poking around found it. Allow me
to start by saying this code is *bad*, in every conceivable meaning of the
term.

A quick compile complains about bzero, and so it should - what the heck is
bzero? It's not defined anywhere in the code. Apparently - from a little
searching - it's just a memset, which leads to the obvious question, why
not use the standard memset? Also, in decode, the variable k is unused,
according to the compiler. That it still exists despite being unused
suggests either you forgot to write some code, or you're using one of the
other variables incorrectly - assigning to j when you should be assigning
to k, say. There are other possibilities, of course, but the unused
variable warning is quite sufficient to render the entire piece of code
questionable.

Okay, fine, it compiles. Let's run it. Hmm. No prompt, no nothing. So
I give it some input to see what happens - I type "woof". It spews out a
"cannot allocate memory" message and quits. Well, if it didn't want
"woof" as an input, why didn't it ask for what it did want?

So I read the code. It wants something called "cases". I'll give it
three and see what happens.

More waiting for unknown things to happen. Attempting to read through
your readinput function proves... futile, really. It's bad, evil, nasty.
It doesn't "read input", it loops, it jumps, it calculates, it glues, it
appends, it does all sorts of weird and wonderful things. A line such as
if (!(j + 1) % 2 && j < (c * 2) - 1) has absolutely no business in a
"readinput" function, the purpose of which is - from the name, at least -
to simply _read_ the input, possibly with validation. Not to process it,
store it, redirect it, do database lookups from it, or stuff it, quite
possibly incorrectly. into buffers it probably shouldn't be touching other
than to store one piece of finally-accepted data into.

However... we'll send some text at it, since it seems to want three pieces
of data. I give it "This is a test." and it promptly spews "Wrong input
format". Really? So why didn't it tell me what format it wanted? Let's
try again.

Give it a "3", give it "woof" and... it pukes. All in all, a most
unfriendly application, so let's ignore that and focus on the code.

While wading through it, I see some odd things. For example, I see chcode
= *foo - 97; the purpose of which isn't entirely clear. Oops... it looks
like this is intended to produce a character value, presumably on the
notion that, say, 'a'-97 == 0 or some such. Except that this notion can't
cope with different cases, for one thing, and isn't portable, as there's
no guarantees about the order of characters or what their numeric values
are.

A little further on, we see hchcount = 0. hchcount? What, exactly, is an
hch, and why are you counting them? No indication is given. Nor is there
any indication of what an sch is and why you're counting those.

On we go to decode(). Here's the function header:

void decode(int *hf, int *sf, char *s, char *hch, char *sch, int f)

Yeesh. That's no fewer than 5 separate things you're planning on
modifying. You're going to modify hf and sf and s and hch and sch. I've
met *very* few functions which actually do so much work that they require
*five* separate outputs. Indeed, I'd tend to suggest that such a function
needs a complete redesign.

For example, a decompression function might return three things - the
decompressed data, the size of the decompressed data, and a result code.
You're returning five things, but you're using completely non-descriptive
names for the parameters, so one has to simply guess what the function
actually means.

Moving on to main... there are 9 separate variables declared in main.
That's actually a _lot_ of variables for a single function, and this is
compounded by using some of the worst variable names imaginable; there is
absolutely nothing about "schars" which indicates what it really is, and
the comment isn't clear, either - what is a "diff character"? While
we're at it, what's with this: scanf("%d", &cases); ? Not even an
attempt to validate the input.

Between lack of comments, bad variable names, overly-busy functions,
non-standard functions, functions which do things other than what they
claim to do, non-portable assumptions, lack of prompts for inputs and the
use of what I'd regard as being at _best_ a truly bizarre handling of user
inputs, the best thing that could happen to this code would be to print it
out, gather around a campfire with a few wiccan priestesses, burn it while
chanting ritual cleansing mantras, then bury the ashes for all time.
Nov 14 '05 #11
Kelsey Bjarnason <ke*****@xxnospamyy.lightspeed.bc.ca> writes:
[...]
Okay, fine, it compiles. Let's run it. Hmm. No prompt, no nothing. So
I give it some input to see what happens - I type "woof". It spews out a
"cannot allocate memory" message and quits. Well, if it didn't want
"woof" as an input, why didn't it ask for what it did want?


If I'm not mistaken, that behavior is imposed by the problem
description. (It's one of the problems at
<http://acm.uva.es/problemset/>.)

No comment on the rest of your criticisms.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #12

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

Similar topics

34
by: Richard Hunt | last post by:
I'm sorry for asking such a silly question, but I can't quite get my head around malloc. Using gcc I have always programmed in a lax C/C++ hybrid (which I suppose is actually c++). But I have...
7
by: Fatted | last post by:
I'm trying to learn how to create arrays dynamically. But its just not happening. Have a look at code below and point and laugh where appropriate... First part of program, I'm using an array of...
58
by: lasek | last post by:
Hi all..i'm here another time..for a simple question: #include <stdlib.h> #include <stdio.h> int main(void) { /* ** I know that someone else use different malloc ** instruction
36
by: Martin Andert | last post by:
Hello, I have a question regarding malloc and free. Here my code sample: int main() { /* allocating dynamic memory for array */ int* array = (int*) malloc(5 * sizeof(int)); /* ... program...
54
by: Neo | last post by:
Hi Folks, I've a simple qestion related to dynamic memory allocation in C here is the code: #include <stdio.h> int main() {
40
by: madireddy | last post by:
Hi, Inside a program how do i find out what size has been allocated to pointer using malloc. eg... int *p; p=(int*)malloc(1024*sizeof(int)); now how do find how much has been allocated to p?...
12
by: gooch | last post by:
I originally posted the following code in a group discussing threads but after further research I think I have a c question about the code. I know there are a couple of non standard c includes here...
68
by: James Dow Allen | last post by:
The gcc compiler treats malloc() specially! I have no particular question, but it might be fun to hear from anyone who knows about gcc's special behavior. Some may find this post interesting;...
82
by: quiberon2 | last post by:
Hi, Sorry if it might be a stupid question but what should returns malloc(0) ? void *ptr = malloc(0); I am running gcc 3.3.5 and a non-null address is returned. ( in the compiler that I am...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
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: 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
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
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
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
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,...

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.