Reputation: 901
My program is written in C and it is a disk emulator. I finished writing it and it runs when I comment out certain lines of my test program, but I get a memory error where I un-comment them. I suspect it is with my char* 's.
The line I comment out (and where the program crashes) is
free(buffer);
where buffer is the char* that the string of bytes that was read into from the disk. It was initially allocated 30 bytes using malloc.
char* buffer = (char *) malloc(sizeof(char) * 30);
There is too much to just post it all here, so I am going to put the parts where I am writing/copying to char* 's in the hopes that someone will see what I am doing wrong.
I don't think it is anything too complicated, I am just not familiar enough with C the recognize obvious memory mistakes.
// In the event of a cache miss:
// block_buffer to pass to add_cache_entry
char cMissBuffer[BLOCK_SIZE];
// read content of block from disk
fread(cMissBuffer,sizeof(char),BLOCK_SIZE,diskEntity.pBlockStore);
// add to cache
if(1==add_cache_entry(i,cMissBuffer)) return 1;
.
.
.
// some of what is in add_cache_entry
int add_cache_entry(int v, char *block_buffer)
{
// ...
// construct a new queue element
QueueElement *block_to_cache = (QueueElement*)malloc(sizeof(QueueElement));
block_to_cache->blkidx = v;
block_to_cache->content=(char*)malloc(BLOCK_SIZE);
strcpy(block_to_cache->content,block_buffer);
// ...
}
In the test, BLOCK_SIZE is 5, QueueElement is a struct, content is a char* with BLOCK_BYTES of info.
Here is an excerpt from running the executable (dumping the queue)...I think that the lack of a '\0' could have something to do with the issue...
after adding cache entry (5):
DUMP:
BLOCK 5 FLAG:0 CONTENT:222220000000
BLOCK 4 FLAG:0 CONTENT:222220000000
BLOCK 3 FLAG:0 CONTENT:000000000000
BLOCK 2 FLAG:0 CONTENT:000000000000
BLOCK 1 FLAG:1 CONTENT:11100
I think I get extra space because malloc allocates more space than I require, but I read that is normal.
Any thoughts?
Upvotes: 0
Views: 70
Reputation: 122011
A probable cause for the behaviour is that strcpy()
requires the source string to be null terminated, which is not the case here as fread()
does not append a null terminator for you (nor could it in this case as fread()
is reading the exact buffer size). strcpy()
also appends a null terminator which means the strcpy()
call will definitely be writing beyond the block_to_cache->content
buffer.
If the data is not be used as a C style string use memcpy()
to copy the data instead:
memcpy(block_to_cache->content, block_buffer, BLOCK_SIZE);
Other points:
fread()
, to ensure it successfully populated the buffer before attempting to use it.malloc()
(see Do I cast the result of malloc?).malloc()
to ensure memory was successful allocated.sizeof(char)
is guaranteed to be one so can be removed from argument to malloc()
.Upvotes: 3