CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Malloc not working in larger program

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Mark Scott



Joined: 18 Sep 2003
Posts: 2

View user's profile Send private message

Malloc not working in larger program
PostPosted: Thu Sep 18, 2003 11:31 am     Reply with quote

I have a PPP and TCP-IP stack that I have written for our PIC-18 based device, however, while going through efforts to optimize memory usage a bit more I was going to switch to using malloc for several pieces of code that require varying amounts of memory. However, I always get a null back from malloc, (even on a small piece of memory, such as 8 bytes).

I know I have more than enough memory left over to do it, I can set the variable at compile time (unsigned char strVals[8]) and it works great.

I am running 3.178, which I upgraded to this morning hoping it would fix malloc. However, it didn't change anything.

The interesting thing to note is that malloc appears to work fine in a very small program I use for testing functionality.

I am including stdlibm.h and as far as I can tell everything should be working. For these functions it would be much nicer to be able to dynamically allocate memory at runtime, so this is very frustrating.

Anybody have advice on this subject?

Thanks,
Mark E. Scott Jr.
mscott@awfs.net
Neutone



Joined: 08 Sep 2003
Posts: 839
Location: Houston

View user's profile Send private message

Re: Malloc not working in larger program
PostPosted: Thu Sep 18, 2003 3:27 pm     Reply with quote

Mark Scott wrote:
I have a PPP and TCP-IP stack that I have written for our PIC-18 based device, however, while going through efforts to optimize memory usage a bit more I was going to switch to using malloc for several pieces of code that require varying amounts of memory. However, I always get a null back from malloc, (even on a small piece of memory, such as 8 bytes).

I know I have more than enough memory left over to do it, I can set the variable at compile time (unsigned char strVals[8]) and it works great.

I am running 3.178, which I upgraded to this morning hoping it would fix malloc. However, it didn't change anything.

The interesting thing to note is that malloc appears to work fine in a very small program I use for testing functionality.

I am including stdlibm.h and as far as I can tell everything should be working. For these functions it would be much nicer to be able to dynamically allocate memory at runtime, so this is very frustrating.

Anybody have advice on this subject?

Thanks,
Mark E. Scott Jr.
mscott@awfs.net


What do you mean by dynamically allocate memory at runtime? Variable memory within a local function that is not static, may be reused by the compiler in other functions for non static variables provided the functions do not call each other. The compiler does a good job of optimizing RAM usage in this respect. When optimizing program memory I tend to look at the frequency of bank jumps in the listing file. When their are a lot of bank jumps it can make a big difference to assign a specific address to just a few variables to reduce bank jumps.
Guest








PostPosted: Thu Sep 18, 2003 6:40 pm     Reply with quote

Quote:
What do you mean by dynamically allocate memory at runtime? Variable memory within a local function that is not static, may be reused by the compiler in other functions for non static variables provided the functions do not call each other. The compiler does a good job of optimizing RAM usage in this respect. When optimizing program memory I tend to look at the frequency of bank jumps in the listing file. When their are a lot of bank jumps it can make a big difference to assign a specific address to just a few variables to reduce bank jumps.


Well, when I write the program I don't know how big a packet may be. I may be just transmitting 8 bytes for an ICMP echo or I may have to allocate enough memory to store 30+ bytes on an echo reply because the sender gave me data along with the echo packet (which I must reply with).

So, I do this:

void SendICMPEcho(int8 EchoType, ....., unsigned char *Data, int8 DataLength)
{
unsigned char *sPingBuf;

sPingBuf = malloc(DataLength + 8);

memcpy(&sPingBuf[8], &Data[0], DataLength);

}

Something like that is desirable so I only use the lowest amount of memory I need. If I knew that the packet was always going to be 8 bytes, I would have just done unsigned char sPingBuf[8], but I can't rely on that.

Thanks,
Neutone



Joined: 08 Sep 2003
Posts: 839
Location: Houston

View user's profile Send private message

PostPosted: Fri Sep 19, 2003 8:24 am     Reply with quote

Anonymous wrote:
Quote:
What do you mean by dynamically allocate memory at runtime? Variable memory within a local function that is not static, may be reused by the compiler in other functions for non static variables provided the functions do not call each other. The compiler does a good job of optimizing RAM usage in this respect. When optimizing program memory I tend to look at the frequency of bank jumps in the listing file. When their are a lot of bank jumps it can make a big difference to assign a specific address to just a few variables to reduce bank jumps.


Well, when I write the program I don't know how big a packet may be. I may be just transmitting 8 bytes for an ICMP echo or I may have to allocate enough memory to store 30+ bytes on an echo reply because the sender gave me data along with the echo packet (which I must reply with).

So, I do this:

void SendICMPEcho(int8 EchoType, ....., unsigned char *Data, int8 DataLength)
{
unsigned char *sPingBuf;

sPingBuf = malloc(DataLength + 8);

memcpy(&sPingBuf[8], &Data[0], DataLength);

}

Something like that is desirable so I only use the lowest amount of memory I need. If I knew that the packet was always going to be 8 bytes, I would have just done unsigned char sPingBuf[8], but I can't rely on that.

Thanks,


I believe your best option is to declare an buffer array that is large enough to hold the bigest packet you have to handle. You don't have to use the enitre buffer every time. I would declare the variable as global rather than have data copied around when functions are called. That will save a great deal of memory and processing time.
ABS
Guest







malloc returns null
PostPosted: Wed May 19, 2004 4:42 am     Reply with quote

I have a similar problem with malloc - It always returns NULL. I am also writing network code and agree that dynamic memory would be most useful. Is there a trick?

Can CCS provide us with examples and documentation about Dynamic Memory?

Can CCS or somebody explain how malloc can always fail?




(more documentation about writing to flash program memory is also good)
abs



Joined: 19 May 2004
Posts: 5

View user's profile Send private message Visit poster's website

malloc free bug hang traverse loop
PostPosted: Wed May 19, 2004 9:56 am     Reply with quote

I noticed that 'free()' breaks after a few (on the third) freeing. The free routine calls 'traverse()'. Traverse walks to the end of the freed memory and spins on the last node.

I will investigate further. Has somebody else noticed this? I am sure you have --- CCS, how about you? Is there a fix in 3.191?
abs



Joined: 19 May 2004
Posts: 5

View user's profile Send private message Visit poster's website

dynamic_memory malloc free traverse bug error infinite loop
PostPosted: Wed May 19, 2004 10:08 am     Reply with quote

Originally, I had problems compiling a program that used stdlibm.h and 'malloc()' and 'free()'.

The following use of pragma (found in other postings) allowed the compiler to finish.

Then malloc would always return null.

So, I moved the #include <stdlibm.h> statement to locate immediately following the #pragma USE DYNAMIC_MEMORY statement which follows the device statements at the top of the program:

#include <18F258.h>
...Device statements...
#pragma USE DYNAMIC_MEMORY
#include <stdlibm.h>

Then malloc seemed to work where I expected it. Now the traverse routine fails on the third freeing, an infinite loop.
Guest








malloc free traverse stdlibm hack it
PostPosted: Wed May 19, 2004 11:32 am     Reply with quote

I'm not sure what helped, but malloc and free work in my larger than an example program. I changed a few things in <stdlibm.h>.

I changed the casts like '(long)node->next' to '(node_t *)node->next'. I also changed in free the line 'ptr=NULL;' to '*ptr=NULL;', but I don't think ptr matters then.

I also save the value of 'node->next' at the top of the traverse loop for debugging.
abs



Joined: 19 May 2004
Posts: 5

View user's profile Send private message Visit poster's website

PostPosted: Wed May 19, 2004 12:06 pm     Reply with quote

I found that my change to ptr and using saveing node->next made no effect.

I also plased a '#use *=16' directive at the top of my program, but I don't know what that does ??? Yet, it may have helped, CCS, eh?
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group