Modify buffer passed as a pointer - c

I'm trying to read into a buffer passed as a pointer to this function. memcpy() works fine and the data is stored correctly in buffer, but when I access buffer outside of the function it is null. There's some pointer issue I'm not getting here.
Here's the code, I took out most of it, I know it copies the data correctly, but it doesn't pass it to the buffer pointer. Ideas?
int read(file file, char *buffer , int maxlen) {
int bytes_read;
// copy data to file buffer
bytes_read = min(maxlen, file->file_size - file->cursor);
buffer = (char*) malloc(bytes_read);
memcpy(buffer , file->buffer + file->cursor, bytes_read);
return bytes_read;
}

The problem is pretty simple: you are modifying the variable "buffer". Since it is passed by value and not by reference, the calling function doesn't see the change. In order to make the change to buffer visible, you need to pass in a pointer to buffer.
Your function would then look like this:
int read(file file, char **buffer , int maxlen) {
int bytes_read;
// copy data to file buffer
bytes_read = min(maxlen, file->file_size - file->cursor);
*buffer = (char*) malloc(bytes_read);
memcpy(*buffer , file->buffer + file->cursor, bytes_read);
return bytes_read;
}
to call the function:
rv = read(file, &buffer, maxlen);

You cannot modify buffer directly because C uses pass by value with parameters. Therefore it is a copy of the pointer you are modifying. To change the pointer you need to change your function prototype to take a char** and allocate to the first level of indirection on that.
As a crude example of this:
void read(char** buffer , int byte_size) {
*buffer = (char*) malloc(byte_size);
}
and use where required with something like
char* buffer;
read(&buffer,10); /* now buffer points to dynamically allocated array of 10 chars */

Related

Passing a char buffer to function

I have some problems with a pointer. My idea was to pass a buffer to a function in order to store the return data in this buffer. But, I do not know if it will work.
void main()
{
char *buf = malloc(sizeof(char) *buf);
memset(buf, 0x00, BUF_SIZE);
sendCommand(buf);
}
sendCommand(char *buf)
{
write(fd, "some commands", strlen("some commands"));
readResponse(buf);
}
readResponse(char *buf)
{
read(fd, buf, nbytes);
}
I know there is no error handling up to now. And some variables are not well defined. It just depends on the passing buffer. Will I see the data that I get in readResponse() in my main function?
As in readResponse() as you read nbytes into buffer pointed by buf ,so you will get that data in main .
Some improvements to be done -
1. void main() -> int main(void) or int main(int argc, char *argv[])
2. char *buf = malloc(sizeof(char) *buf); -> char *buf = malloc(BUF_SIZE); // sizeof(char)=1 or maybe something you desire (not sure though what you want ??)
Note - remember to free allocated memory.
You have a remarkable number of significant problems in the code you presented, considering how short it is. Other answers have addressed those, though, and your question is not actually about any of them:
Will I see the data I get in readResponse() in my main function?
Yes, provided that argument buf is a pointer to an array large enough to accommodate nbytes bytes, and that the read() call in fact successfully reads any bytes, those bytes will afterward be visible in main() via the pointer it passed to readResponse(). More generally, if you pass a pointer as a function argument, the called function may manipulate the pointed-to object, including by modifying those parts of it that are not const. That's how the read() function itself is able to store the bytes it reads into your buffer, after all.
This won't do what you think it does:
char *buf = malloc(sizeof(char) *buf);
Did you mean to multiply with BUF_SIZE?

Memory of first element in dynamic char array

My array is defined like this
int buffSize = 80;
char* buff = (char*) malloc(sizeof(char) * buffSize);
First, I thought &buff should be the same as &buff[0], but apparently, it isn't! Did I miss something here?
This statement prints two different values for those two:
printf("COMPARE: buff=%u, buff[0]=%u\n", &buff, &buff[0]);
Second, the reason I asked is because I'm trying to create a big buffer and "manually" divide it up to use with getline.
Basically, I'd like to do something like this:
int byte_read, total_read = 0;
do
{
read = getline(&buff[totalRead], buffSize, inFile); //where inFile is just a file handler
totalRead += read;
}
while (byte_read > 0);
buff is a pointer, and &buff is the address of that pointer. On the other hand, &buff[0] is the address of the location the pointer points to, and should have the same value as buff.
In summary, expect buff and &buff[0] to have the same value.

What to use instead of sizeof(void)?

I'm trying to copy a file. I'm using a borrowed code snippet, and there's a line of it which errors which confuses me.
int fileread = open("original.txt", O_RDONLY);
void *buffer;
buffer = malloc(sizeof(void) * size); /*This line gives "Incomplete type not allowed."*/
int nread = read(fileread,buffer,size);
int filewrite = open("original.txt.backup",O_CREAT | O_RDWR, 0644);
write(filewrite,buffer,size);
close(filewrite);
close(fileread);
What should I be using instead? I was thinking char*, but I want to make sure I'm understanding the process going on here.
If you want to allocate a buffer of size bytes, and have buffer point to the beginning of it:
void *buffer = malloc(size);
if (buffer == NULL) {
/* allocation failed */
}
/* ... */
But if you want to do something with the data in the buffer, it will need to have a valid type. An array of unsigned char is a common way to manage buffers of arbitrary contents:
unsigned char *buffer = malloc(size);
/* as above */
sizeof() returns the size of your type. Honestly I think you should just change it to
char *buffer;
buffer = malloc(sizeof(char) * size);
Sizeof(void) makes zero sense

How to concat two char * in C?

I receive a char * buffer which have the lenght of 10.
But I want to concat the whole content in my struct which have an variable char *.
typedef struct{
char *buffer;
//..
}file_entry;
file_entry real[128];
int fs_write(char *buffer, int size, int file) {
//every time this function is called buffer have 10 of lenght only
// I want to concat the whole text in my char* in my struct
}
Something like this :
real[i].buffer += buffer;
How can I do this in C ?
In general, do the following (adjust and add error checking as you see fit)
// real[i].buffer += buffer;
// Determine new size
int newSize = strlen(real[i].buffer) + strlen(buffer) + 1;
// Allocate new buffer
char * newBuffer = (char *)malloc(newSize);
// do the copy and concat
strcpy(newBuffer,real[i].buffer);
strcat(newBuffer,buffer); // or strncat
// release old buffer
free(real[i].buffer);
// store new pointer
real[i].buffer = newBuffer;
You can use strcat(3) to concatenate strings. Make sure you have allocated enough space at the destination!
Note that just calling strcat() a bunch of times will result in a Schlemiel the Painter's algorithm. Keeping track of the total length in your structure (or elsewhere, if you prefer) will help you out with that.
I am not clear. Do you want:
to concatenate every one of the 10 character buffers you receive into one array, pointed at by one real[0].buffer, or
do you want each 10 character buffer to be pointed at by a different real[i].buffer, or
something else?
You will need to allocate enough space for the copy of the buffer:
#include <stdlib.h>
//...
int size = 10+1; // need to allocate enough space for a terminating '\0'
char* buff = (char *)malloc(size);
if (buff == NULL) {
fprintf(stderr, "Error: Failed to allocate %d bytes in file: %s, line %d\n",
size, __FILE__, __LINE__ );
exit(1);
}
buff[0] = '\0'; // terminate the string so that strcat can work, if needed
//...
real[i].buffer = buff; // now buffer points at some space
//...
strncpy(real[i].buffer, buffer, size-1);

read function: copying buffer to another char array

I'm new to C and am trying to use the read function. I want to take what's in the buffer (tempChar) and put it in another char array (str). This is so I can run the read function again and add on to str later (because tempChar will be rewritten by the 2nd read function). Like this:
char tempChar;
read(0, &tempChar, 10);
char *str;
str= (char*) malloc(10);
memcpy(str, &tempChar, fileSize); /*I'm doing something wrong here*/
All this so I can rerun:
read(0,&tempChar, 1);
str= realloc(str, 11);
str[10]=tempChar;
It compiles fine, but it gives me a segmentation fault when I actually try to run it.
Any ideas? Thanks a bunch.
you need to have enough storage to store the 10 characters you are reading
you declared
char tempChar
which can hold 1 character.
Instead declare tempChar as
char tempChar[10];
char tempChar;
read(0, &tempChar, 10);
You are reading 10 characters from the file into memory only the size of a single char.
char tempChar only reserves memory for a single character, &tempChar points to this single byte of memory.
char *str;
str= (char*) malloc(10);
// why not now do ?
read(0, str, 10);
char tempChar;
Only allocates 1 byte. So you can only hold there 1 char. When you memcpy() you request to copy 10 bytes, which do not exist. Hence you read memory you should not causing Undefined Behaviour (which gives you the SegFault).
You should do something like you did with malloc() for str or declare a local array like char chatTemp[10]. Note: malloc() does not require a cast in C.
If you want to read twice and put the results next to each other in the same buffer, you don't need a temporary buffer for that: you can use pointer arithmetic to tell read to use the second half of the original buffer. Like so:
char buf[10];
ssize_t nread = read(0, buf, 5);
if (nread < 0)
error();
else
{
nread = read(0, buf + nread, sizeof buf - nread);
if (nread < 0)
error();
}
You need to give a file descriptor as a first parameter to read function.. Also you need to allocate char * buffer instead of char tempChar;
Check sample usage

Resources