|
|
View previous topic :: View next topic |
Author |
Message |
Mark Scott
Joined: 18 Sep 2003 Posts: 2
|
Malloc not working in larger program |
Posted: Thu Sep 18, 2003 11:31 am |
|
|
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.
[email protected] |
|
|
Neutone
Joined: 08 Sep 2003 Posts: 839 Location: Houston
|
Re: Malloc not working in larger program |
Posted: Thu Sep 18, 2003 3:27 pm |
|
|
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.
[email protected] |
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
|
|
Posted: Thu Sep 18, 2003 6:40 pm |
|
|
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
|
|
Posted: Fri Sep 19, 2003 8:24 am |
|
|
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 |
Posted: Wed May 19, 2004 4:42 am |
|
|
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
|
malloc free bug hang traverse loop |
Posted: Wed May 19, 2004 9:56 am |
|
|
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
|
dynamic_memory malloc free traverse bug error infinite loop |
Posted: Wed May 19, 2004 10:08 am |
|
|
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 |
Posted: Wed May 19, 2004 11:32 am |
|
|
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
|
|
Posted: Wed May 19, 2004 12:06 pm |
|
|
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? |
|
|
|
|
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
|