-
Problems with malloc
I want to allocate room in a buffer so I can send data through a socket (I've got to write a simple FTP program for class); however, every time I call malloc, it only allocates 4 bytes. I wrote some sample code to test it:
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char* buffer;
buffer = (char*) malloc((size_t)sizeof("Sample string."));
printf("%d\n",sizeof(buffer));
printf("%d\n",sizeof("Sample string."));
free(buffer);
return 0;
}
The output is:
Shouldn't they both say "15"? What am I doing wrong with malloc?
-
sizeof(buffer) returns the size of the pointer named buffer, not the size of the buffer. So you are allocating 15 bytes, but sizeof(buffer) does not show that. You do not need to cast the result of sizeof to size_t.
-
sizeof(buffer) gives you the size of a char *, not the size of the memory attached to the variable called buffer that is of type char * - the key here is that sizeof() is a compile-time resolved resource - it doesn't know anything about what happens in malloc, or if you do something like this:
Code:
char array[100];
char *buffer = array;
Quite clearly, buffer points to an array of 100 chars, but sizeof(buffer) will be 4 on most systems (2 or 8 are other likely numbers in 16 and 64-bit systems respectively, 100 is NEVER going to be the answer).
--
Mats
-
How can I determine the size of the buffer?
(I apologize, I haven't written C for the longest.)
Edited to include: In the client/server I have written, it will only copy the first four characters from the source file into the destination file, even though I am allocating the same size in both buffers. I will post code.
-
In this case you already know the size of the buffer since you are using it. You just need to store it somewhere to keep track of it.
-
I agree with laserlight - _YOU_ need to track the size of memory allocations in some way. The very easy way is to make it a constant, but if the allocations vary greatly in size, you may want to optimize it. You could use a struct, e.g.
Code:
struct memallocation
{
size_t size;
void *ptr;
};
Or just have two parameters that you use each time you allocate memory.
Of course, another option is to just make sure you allocate the right amount in the first place, e.g. read a string into a fixed storage [make sure it's large enough], then use strlen() to figure out it's length and use malloc(len+1) [+1 to add the zero-termination].
--
Mats
-
Here is the majority of the reading and sending from the client side. Again, the server only gets four letters of the destination file.
Code:
//CLIENT
// Get the file size
fseek (fpRead , 0 , SEEK_END);
fileSize = ftell(fpRead);
rewind (fpRead);
// Allocate memory to contain the whole file.
buffer = (char*)malloc(fileSize);
// Read the file into the buffer.
fread(buffer,1,fileSize,fpRead);
//Write to socket.
n = write(sockfd,buffer,strlen(buffer));
if (n < 0)
error("ERROR writing to socket");
Server code:
Code:
//SERVER
//Parse fileSize received from socket
fileSize = atoi(command);
//Allocate space for incoming file
buffer = (char*) malloc (fileSize);
//Read in file from socket
n = read(newsockfd,buffer,sizeof(buffer));
if (n < 0)
error("ERROR reading from socket"
//Write buffer to file
fpWrite=fopen("recieved.txt", "ab+");
fwrite(buffer,1,fileSize,fpWrite);
fflush(fpWrite);
My file is always corrupt or truncated. Any ideas?
EDITED: Oh, I forgot to take into account '\0'. I added 1 to my mallocs, and it worked flawlessly. Thanks everyone! :)
-
If you want to do this with some flexibility, e.g. allowing LARGE files to be transferred, you should consider transmitting the file in pieces - consider that it's quite possible to create files much larger than physical memory, which even if you CAN allocate a large enough buffer with malloc, will definitely make for a much slower solution than copying the file "piece-by-piece". Sure, if the file is small, you can load up the entire file in memory and then transmit it via a socket, but if the file is large there are two problems:
1. IP packets are limited in size, so you would be sending multiple packets.
2. If you don't have at least as much physical RAM as the file is large, swapping will happen.
Copying something like 1.5 to 4KB at a time solves two problems:
1. You don't need to allocate a variable size memory.
2. You can copy ANY size file, no matter what it's size is.
--
Mats